标签:codeforces 想法 贪心
题意:
k次操作 每次选择一行或一列 得到所选数字的和 并将所选数字同时减去p 问最多得到多少
思路:
重点在消除行列间的相互影响
由于每选一行所有列所对应的和都会-p 那么如果选了i次行 则列会-i*p 同理选列
那么影响就可以这样表示 -p*i*(k-i) 把影响提出来 这样行列就不影响了
对于行或列 单独处理时相当于一维的东西 贪心即可
代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; #define N 1010 #define M 1000010 typedef __int64 ll; ll sum[2][N]; ll res[2][M]; ll ans,p; int n,m,k; struct node { ll val; int x; bool operator<(const node fa) const { return val<fa.val; } }u; priority_queue<node> q; int main() { int i,j; ll w; scanf("%d%d%d%I64d",&n,&m,&k,&p); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%I64d",&w); sum[0][i]+=w; sum[1][j]+=w; } } while(!q.empty()) q.pop(); for(i=1;i<=n;i++) { u.x=i; u.val=sum[0][i]; q.push(u); } for(i=1;i<=k;i++) { u=q.top(); q.pop(); res[0][i]=res[0][i-1]+u.val; u.val-=p*m; q.push(u); } while(!q.empty()) q.pop(); for(i=1;i<=m;i++) { u.x=i; u.val=sum[1][i]; q.push(u); } for(i=1;i<=k;i++) { u=q.top(); q.pop(); res[1][i]=res[1][i-1]+u.val; u.val-=p*n; q.push(u); } ans=max(res[0][0]+res[1][k],res[0][k]+res[1][0]); // hang or lie for(i=1;i<k;i++) ans=max(ans,res[0][i]+res[1][k-i]-p*i*(k-i)); printf("%I64d\n",ans); return 0; }
CodeForces 446B DZY Loves Modification,布布扣,bubuko.com
CodeForces 446B DZY Loves Modification
标签:codeforces 想法 贪心
原文地址:http://blog.csdn.net/houserabbit/article/details/37822015