倉庫選址(前綴和、數學)

在這裏插入圖片描述
解題思路:
二維前綴和(O(NM))
這個算法可能比較簡單易懂,二維前綴和的實現與計算就不再贅述了,可以上網查一下
在暴力方法一中每次枚舉一個座標都要把到所有點的距離重新算一遍,其實沒必要。
若倉庫在點 (x,y) 處,現在將倉庫移動到點 (x+1,y) ,那麼對於左上角爲(1,1),右下角爲(x,m)的矩陣,所有點到達倉庫的距離都+1,對於左上角爲(x+1,1),右下角爲(n,m)的矩陣,所有點到達倉庫的距離都-1。若倉庫在點 (x,y) 處,現在將倉庫移動到點 (x,y+1)同理計算即可。

#include<bits/stdc++.h>
using namespace std;
int s[110][110];
inline int calc(int A,int B,int C,int D)
{
	return s[C][D]-s[A-1][D]-s[C][B-1]+s[A-1][B-1];
}
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int m,n,now=0,nxt=0,ans=0x3f3f3f3f;
		cin>>m>>n;
		for(int i=1;i<=n;++i)
		{
			for(int j=1;j<=m;++j)
			{
				int a;
				cin>>a;
				s[i][j]=a+s[i-1][j]+s[i][j-1]-s[i-1][j-1];
				now+=a*(i-1+j-1);
			}
		}
		for(int i=1;i<=n;++i)
		{
			nxt=now;
			for(int j=1;j<=m;++j)
			{
				ans=min(nxt,ans);
				nxt+=calc(1,1,n,j)-calc(1,j+1,n,m);
			}
			now+=calc(1,1,i,m)-calc(i+1,1,n,m);
		}
		cout<<ans<<endl;
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章