這題要求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;
}
(這其實是我抄的榜一的代碼,見諒