Social Distancing
题目描述:
如今,梦网王国正遭受着全国性的流行病。 幸运的是,宝宝社长正在与疾病控制中心
进行有效合作,他们正在尽最大努力使一切都受到控制。宝宝社长宣布了一项社会隔离政策,以防止病毒传播。 作为
的负责人,您需要研究以下问题:
有n个人需要观察,并且您已经在
维平面上的
中设置了监视器。 每个人都应保持在r到显示器的距离之内。 您还必须使它们尽可能远离彼此。 为了简化问题,您只能将它们分配给整数坐标。
请最大化
,
其中
表示第
个人与第
个人之间的欧几里得距离。
输入描述:
有多个测试用例。 输入的第一行包含一个整数
,表示测试用例的数量。
对于每个测试用例,唯一的行包含两个整数
。
输出描述:
对于每个测试用例,请在一行中输出答案。
样例输入:
2
4 2
5 10
样例输出:
64
2496
思路:
动态规划。
首先我们可以想到n个点的距离和为:
由于这个式子中有减法,较难维护,所以我们考虑把他转化成加法的形式:
前一项可以直接得到,后一项可以通过勾股定理求得,然后就可以
了
由于数据范围较小,也可以算出所有答案后打表查询来做。
1:
( 预处理+ 查询)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=300;
const int mx=32;
int dp[9][MAXN*2][MAXN*2],ans[MAXN][MAXN];
vector<pair<int,pair<int,int> > > vec;
void ycl()
{
int s=0;
for(int i=-mx;i<=mx;++i)
for(int j=-mx;j<=mx;++j)
vec.push_back(make_pair(i*i+j*j,make_pair(i,j)));
sort(vec.begin(),vec.end());
memset(dp,-0x3f*2,sizeof(dp));
dp[0][MAXN][MAXN]=0;
for(int r=1;r<=30;++r){
while(vec[s].first<=r*r){
for(int i=1;i<=8;++i)
for(int j=MAXN-r*i;j<=MAXN+r*i;++j)
for(int k=MAXN-r*i;k<=MAXN+r*i;++k)
dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-vec[s].second.first][k-vec[s].second.second]+vec[s].first);
s++;
}
for(int n=1;n<=8;++n)
for(int h=0;h<2*MAXN;++h)
for(int l=0;l<2*MAXN;++l)
if(dp[n][h][l]>0)
ans[n][r]=max(ans[n][r],n*dp[n][h][l]-((h-MAXN)*(h-MAXN)+(l-MAXN)*(l-MAXN)));
}
}
int t,n,r;
int main(){
ycl();
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&r);
printf("%d\n",ans[n][r]);
}
}
2:
打表,总时间复杂度 。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int ans[50][50]={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,4,16,36,64,100,144,196,256,324,400,484,576,676,784,900,1024,1156,1296,1444,1600,1764,1936,2116,2304,2500,2704,2916,3136,3364,3600},{0,8,32,76,130,224,312,416,554,722,896,1064,1248,1512,1746,2016,2264,2600,2888,3218,3584,3912,4344,4712,5138,5612,6062,6536,6984,7520,8084},{0,16,64,144,256,400,576,784,1024,1296,1600,1936,2304,2704,3136,3600,4096,4624,5184,5776,6400,7056,7744,8464,9216,10000,10816,11664,12544,13456,14400},{0,24,96,218,384,624,880,1188,1572,2014,2496,2984,3520,4224,4870,5616,6336,7224,8056,9008,9984,10942,12080,13144,14326,15624,16896,18184,19488,20968,22480},{0,36,144,324,576,900,1296,1764,2304,2916,3600,4356,5184,6084,7056,8100,9216,10404,11664,12996,14400,15876,17424,19044,20736,22500,24336,26244,28224,30276,32400},{0,48,192,432,768,1224,1740,2356,3102,3954,4896,5872,6960,8280,9564,11016,12456,14160,15816,17666,19584,21500,23688,25808,28122,30624,33120,35664,38266,41200,44076},{0,64,256,576,1024,1600,2304,3136,4096,5184,6400,7744,9216,10816,12544,14400,16384,18496,20736,23104,25600,28224,30976,33856,36864,40000,43264,46656,50176,53824,57600}};
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n,r;
scanf("%d%d",&n,&r);
printf("%d\n",ans[n][r]);
}
}