http://codeforces.com/problemset/problem/446/B
分别将每行的和与每列的和存入优先队列,计算操作n次的最大和,保存每一次结果。
枚举行和列操作的次数,注意要减去补偿的值。
#include<cstdio> #include<algorithm> #include<queue> #include<iostream> using namespace std; long long a[1005][1005],r[1005],c[1005]; long long rr[1000005],cc[1000005]; int main() { int n,m,k,p; scanf("%d%d%d%d",&n,&m,&k,&p); for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) { scanf("%lld",&a[i][j]); r[i] += a[i][j]; c[j] += a[i][j]; } } priority_queue<long long> q; for(int i = 1;i <= n;i++) { q.push(r[i]); } for(int i = 1;i <= k;i++) { long long temp = q.top(); q.pop(); rr[i] = rr[i-1]+temp; temp -= p*m; q.push(temp); } while(!q.empty()) { q.pop(); } for(int i = 1;i <= m;i++) { q.push(c[i]); } for(int i = 1;i <= k;i++) { long long temp = q.top(); q.pop(); cc[i] = cc[i-1]+temp; temp -= p*n; q.push(temp); } long long sum = -1LL<<60; for(int i = 0;i <= k;i++) { sum = max(sum,rr[i]+cc[k-i]-1LL*p*i*(k-i)); } cout << sum << endl; return 0; }