在一个城市区域内,被划分成了n * m个连续的区块,每个区块都拥有不同的权值,代表着其土地价值。目前,有两家开发公司,A 公司和 B 公司,希望购买这个城市区域的土地。
现在,需要将这个城市区域的所有区块分配给 A 公司和 B 公司。
然而,由于城市规划的限制,只允许将区域按横向或纵向划分成两个子区域,而且每个子区域都必须包含一个或多个区块。 为了确保公平竞争,你需要找到一种分配方式,使得 A 公司和 B 公司各自的子区域内的土地总价值之差最小。
注意:区块不可再分。
思路:前缀和,只能按行或按列分为两块,使得这两块的权值之差最小,先按行分,求出最小差值,然后再按列分,求出最小差值,比较取小即可
#include <bits/stdc++.h>
using namespace std;
int find()
{
int ans=MAX_INT;
int n,m;
int sum=0;
cin>>n>>m;
vector<vector<int> > v(n,vector<int>(m,0));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>v[i][j];
sum+=v[i][j];
}
}
//行的前缀和
vector<int> v1(n,0);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
v1[i]+=v[i][j];
}
}
//列的前缀和
vector<int> v2(m,0);
for(int j=0;j<m;j++)
{
for(int i=0;i<n;i++)
{
v2[j]+=v[i][j];
}
}
//分别求出按行分和按列分的最小值
int h=0;
for(int i=0;i<n;i++)
{
h+=v1[i];
//sum-h为后面几行的前缀和
ans=min(ans,abs(sum-h-h));
}
int vv=0;
for(int j=0;j<n;j++)
{
vv+=v2[j];
ans=min(ans,abs(sum-vv-vv));
}
return ans;
}
int main(void)
{
cout<<find();
return 0;
}