Question link: Click the open link
Question:
Given n rows and M columns of matrix K operations, a constant P
Ans = 0;
For each operation
You can select either one row or one column, ANS + = The number and
Then every number in this row (column) is-= P
Largest ans
Ideas:
First, we finally select row I, then the column selects k-I
If we select all rows and then columns,-= I * P is required for each column selection.
In this case, the end is-= I * (k-I) * P
That is, the impact of all rows on columns.
Then we first propose this I * (k-I) * P, so the selection of rows and columns will not affect each other.
You can consider rows and columns separately.
For the case of Row-only:
Pre-process to select 0 times 1 times · maximum value of K rows H [I]
That is, you can run the queue first.
Similarly, if column processing is performed, L [I] indicates that the maximum value of the zero row is obtained.
Then ans = max (H [I] + L [k-I]-I * (k-I) * P)
Note that the result may be a small negative number. ans =-INF and INF must be large enough.
#include <cstdio>#include <algorithm>#include<iostream>#include<string.h>#include <math.h>#include<queue>using namespace std;#define ll long long#define N 1005#define M 1000005ll a[N][N];ll retc[M], retr[M];priority_queue<pair<ll, ll> > sc, sr;int main() {ll n, m, k, p;while(cin>>n>>m>>k>>p){ while(!sc.empty())sc.pop(); while(!sr.empty())sr.pop(); for(ll i = 1; i <= n; i ++) { for(ll j = 1; j <= m; j ++) { scanf("%I64d", &a[i][j]); } } for(ll i = 1; i <= n; i ++) { ll s = 0; for(ll j = 1; j <= m; j ++) { s += a[i][j]; } sr.push(make_pair(s, i)); } for(ll j = 1; j <= m; j ++) { ll s = 0; for(ll i = 1; i <= n; i ++) { s += a[i][j]; } sc.push(make_pair(s, j)); } for(ll i = 1; i <= k; i ++) { ll s = sr.top().first; ll id = sr.top().second; retr[i] = retr[i-1] + s; s -= p*m; sr.pop(); sr.push(make_pair(s, id)); } for(ll i = 1; i <= k; i ++) { ll s = sc.top().first; ll id = sc.top().second; retc[i] = retc[i-1] + s; s -= p*n; sc.pop(); sc.push(make_pair(s, id)); } ll ans = -(ll)(1e18); for(ll i = 0; i <= k; i ++) { ans = max(ans, retr[i] + retc[k-i] - (ll)i * (k-i) * p); } cout<<ans<<endl; }return 0;}/*2 2 2 21 32 42 2 5 21 32 43 1 3 13213 2 4 11 11 11 13 1 3 10002 3 3 21 1 -1-1 1 11 5 21 11 2 3 4 5 6*/