D is to give a matrix and then perform K operations to subtract P from each element in an entire row or column and then subtract the previous row and column, I did not make it out. We can know that the final result uses X vertical and Y, so the order in which they use will not be affected, then pre-process the maximum value of 1 --- K times and the maximum value of 1 --- K times, and then enumerate X for corresponding processing to reach the final answer.
#include <iostream>#include <cstdio>#include <string.h>#include <queue>#include <algorithm>using namespace std;const int maxn = 1005;__int64 Martix[maxn][maxn],n,m,k,p;__int64 R[maxn*1000],C[maxn*1000];__int64 maxv(__int64 a,__int64 b){ return a>b?a:b;}int main(){ priority_queue<__int64>row,cloun; while(scanf("%I64d%I64d%I64d%I64d",&n,&m,&k,&p)==4) { for(int i =0;i<n; ++i) for(int j=0; j<m; ++j) scanf("%I64d",&Martix[i][j]); for(int i= 0; i<n; ++i) { __int64 a=0; for(int j=0; j<m; ++j) a+=Martix[i][j]; row.push(a); } for(int i=0; i<m; ++i) { __int64 a=0; for(int j = 0; j<n; ++j) a += Martix[j][i]; cloun.push(a); } R[0]=0; __int64 ans=0; for(int i=1 ; i<=k; ++i ) { __int64 rt =row.top();row.pop(); ans+=rt; R[i]=ans; rt-=m*p; row.push(rt); } C[0]=0; ans=0; for(int i =1; i<=k; ++i) { __int64 rt =cloun.top();cloun.pop(); ans+=rt; rt-=n*p; C[i]=ans; cloun.push(rt); } ans=-1000000000000000000; for(__int64 i =0; i<=k; ++i) { __int64 t = R[i]+C[k-i]; __int64 e = p*i*(k-i); t =t-e; ans=maxv(ans,t); } printf("%I64d\n",ans); while(!row.empty())row.pop(); while(!cloun.empty())cloun.pop(); } return 0;}
View code
Codeforces round # ff (Div. 2)