枚举行取了多少次,如行取了i次,列就取了k-i次,假设行列单独贪心考虑然后相加,那么有i*(k-i)个交点是多出来的:dpr[i]+dpc[k-i]-i*(k-i)*p
枚举i取最大值。。。。
As we know, DZY loves playing games. One day DZY decided to play with a n × m matrix. To be more precise, he decided to modify the matrix with exactly k operations.
Each modification is one of the following:
DZY wants to know: what is the largest total value of pleasure he could get after performing exactly k modifications? Please, help him to calculate this value.
The first line contains four space-separated integers n, m, k and p (1 ≤ n, m ≤ 103; 1 ≤ k ≤ 106; 1 ≤ p ≤ 100).
Then n lines follow. Each of them contains m integers representing aij (1 ≤ aij ≤ 103) — the elements of the current row of the matrix.
Output a single integer — the maximum possible total pleasure value DZY could get.
2 2 2 2 1 3 2 4
11
2 2 5 2 1 3 2 4
11
For the first sample test, we can modify: column 2, row 2. After that the matrix becomes:
1 1 0 0
For the second sample test, we can modify: column 2, row 2, row 1, column 1, column 2. After that the matrix becomes:
-3 -3 -2 -2
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; typedef long long int LL; const int maxn=1100; LL dpr[maxn*maxn],dpc[maxn*maxn]; LL col[maxn],row[maxn]; LL a[maxn][maxn]; priority_queue<LL> qc,qr; int n,m,k; LL p; int main() { scanf("%d%d%d%I64d",&n,&m,&k,&p); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { scanf("%I64d",&a[i][j]); col[j]+=a[i][j]; row[i]+=a[i][j]; } } for(int i=0;i<n;i++) qr.push(row[i]); for(int i=0;i<m;i++) qc.push(col[i]); dpr[0]=dpc[0]=0; for(int i=1;i<=k;i++) { LL cc=qc.top(); qc.pop(); LL rr=qr.top(); qr.pop(); dpr[i]=dpr[i-1]+rr; dpc[i]=dpc[i-1]+cc; qc.push(cc-p*n); qr.push(rr-p*m); } LL ans=dpr[0]+dpc[k]; for(int i=1;i<=k;i++) ans=max(ans,dpr[i]+dpc[k-i]-1LL*i*(k-i)*p); printf("%I64d",ans); return 0; }