这题要求n*m矩阵中选择一个点,使得其他点到这个点的哈密顿距离之和最小
题解用的是O(n4)
我也是很无语
这里可以用O(2)来做
做出无权值的二维前缀和,再分别作出以x和y坐标为权值的二维前缀和
for (i=1;i<=n;i++){
for (j=1;j<=m;j++){
scanf ("%d",&a[i][j]);
s[i][j]=a[i][j];
sx[i][j]=a[i][j]*i;
sy[i][j]=a[i][j]*j;
s[i][j]+=(s[i][j-1]+s[i-1][j]-s[i-1][j-1]);
sx[i][j]+=(sx[i][j-1]+sx[i-1][j]-sx[i-1][j-1]);
sy[i][j]+=(sy[i][j-1]+sy[i-1][j]-sy[i-1][j-1]);
}
}
然后对于题意,枚举每个点为仓库,取出
(无权置的前缀和*x坐标-带x权值的前缀和)+(无权置的前缀和*y坐标-带y权值的前缀和)
这就是广义的答案
对于具体的答案
我们必须分为4大块
具体的4部分你们看代码吧
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pi pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define mod 1000000007
using namespace std;
int a[105][105],n,m;
int s[105][105],sx[105][105],sy[105][105];
inline int gs(int a,int b,int c,int d)
{if (a>c||b>d) return 0;
return s[c][d]-s[a-1][d]-s[c][b-1]+s[a-1][b-1];
}
inline int gx(int a,int b,int c,int d)
{if (a>c||b>d) return 0;
return sx[c][d]-sx[a-1][d]-sx[c][b-1]+sx[a-1][b-1];
}
inline int gy(int a,int b,int c,int d)
{if (a>c||b>d) return 0;
return sy[c][d]-sy[a-1][d]-sy[c][b-1]+sy[a-1][b-1];
}
int main (){
int i,j,k,T;
scanf ("%d",&T);
while (T--)
{scanf ("%d%d",&n,&m);
swap(n,m);
memset(s,0,sizeof(s));
memset(sx,0,sizeof(sx));
memset(sy,0,sizeof(sy));
for (i=1;i<=n;i++)
{for (j=1;j<=m;j++)
{scanf ("%d",&a[i][j]);
s[i][j]=a[i][j];
sx[i][j]=a[i][j]*i;
sy[i][j]=a[i][j]*j;
s[i][j]+=(s[i][j-1]+s[i-1][j]-s[i-1][j-1]);
sx[i][j]+=(sx[i][j-1]+sx[i-1][j]-sx[i-1][j-1]);
sy[i][j]+=(sy[i][j-1]+sy[i-1][j]-sy[i-1][j-1]);
}
}
/* cout<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<s[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<sx[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<sy[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;*/
// cout<<gs(1,1,2,2);
int ans=200*100*100*1000;
for (i=1;i<=n;i++)
{for (j=1;j<=m;j++)
{int p1=(s[i][j]*i-sx[i][j])+(s[i][j]*j-sy[i][j]);
int p2=(gs(1,j+1,i,m)*i-gx(1,j+1,i,m))+(gy(1,j+1,i,m)-gs(1,j+1,i,m)*j);
int p3=(gx(i+1,1,n,j)-gs(i+1,1,n,j)*i)+(gs(i+1,1,n,j)*j-gy(i+1,1,n,j));
int p4=(gx(i+1,j+1,n,m)-gs(i+1,j+1,n,m)*i)+(gy(i+1,j+1,n,m)-gs(i+1,j+1,n,m)*j);
int res=p1+p2+p3+p4;
if (res<ans) ans=res;
printf("%d %d %d %d %d,",p1,p2,p3,p4,res);
}
printf("\n");
}
printf ("%d\n",ans);
}
return 0;
}
(这其实是我抄的榜一的代码,见谅