DZY Loves Modification
Hisaishi_Kanade · · 题解
首先,想到一个很神秘的贪心:每次挑出和最大的一行或一列,对其进行操作。
但是它是错的。
那么这是否给了我们启发,行列一起贪心不可行,那我分开贪心呢?
我们设立两个辅助数组,初始
定义
显然
不难想到一个贪心策略,每次在
类似地定义
发现需要一个快速找到最大值,对最大值进行修改的数据结构,堆就可以胜任。
最后考虑如果从
容易发现,
#include <queue>
#include <vector>
#include <algorithm>
int n,m,k,p,i,j;
std::priority_queue<long long> q;
long long f[2][1000005],row[1005],col[1005],a[1005][1005];
int main()
{
int t=1;
while(t--)
{
long long ret=-(1ll<<60),delta,mid;
n=read();m=read();
k=read();p=read();
for(i=1;i<=k;++i)
f[0][i]=f[1][i]=0;
for(i=1;i<=n;++i)
row[i]=0;
for(i=1;i<=m;++i)
col[i]=0;
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
a[i][j]=read();
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
row[i]+=a[i][j];
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
col[j]+=a[i][j];
while(!q.empty())
q.pop();
for(i=1;i<=n;++i)
{
q.push(row[i]);
}
delta=m*p;
for(i=1;i<=k;++i)
{
f[0][i]=f[0][i-1]+q.top();
mid=q.top();
q.pop();
q.push(mid-delta);
// printf("%lld\n",q.top());
}
while(!q.empty())
q.pop();
for(i=1;i<=m;++i)
{
q.push(col[i]);
}
delta=n*p;
for(i=1;i<=k;++i)
{
f[1][i]=f[1][i-1]+q.top();
mid=q.top();
q.pop();
q.push(mid-delta);
}
for(i=0;i<=k;++i)
{
ret=std::max(ret,f[0][i]+f[1][k-i]-1ll*i*(k-i)*p);
}
printf("%lld\n",ret);
}
return 0;
}