Codeforces 447D

447D - DZY Loves Modification

思路:将行和列分开考虑。用优先队列,计算出行操作i次的幸福值r[i],再计算出列操作i次的幸福值c[i]。然后将行取i次操作和列取k-i次操作,那么多加的幸福值就是i*(k-i)*p,因为无论先操作行还是列,每操作一次一个格子只减一次p。这样记录下最大的幸福值。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+5;
const int M=1e3+5;
const ll INF=1e18;
priority_queue<ll>row,col;
ll r[N],c[N];
int a[M][M];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,m,k,p;
    cin>>n>>m>>k>>p;
    for(int i=0;i<n;i++)
    {
        ll sum=0;
        for(int j=0;j<m;j++)
        {
            cin>>a[i][j];
            sum+=a[i][j];
        }
        row.push(sum);
    }
    for(int j=0;j<m;j++)
    {
        ll sum=0;
        for(int i=0;i<n;i++)
        sum+=a[i][j];
        col.push(sum);
    }
    for(int i=1;i<=k;i++)
    {
        ll temp=row.top();
        row.pop();
        r[i]=r[i-1]+temp;
        row.push(temp-m*p);
    }
    for(int i=1;i<=k;i++)
    {
        ll temp=col.top();
        col.pop();
        c[i]=c[i-1]+temp;
        col.push(temp-n*p);
    }
    ll ans=-INF;
    for(int i=0;i<=k;i++)
    {
        ans=max(ans,r[i]+c[k-i]-1ll*i*(k-i)*p);
    }
    cout<<ans<<endl;
    return 0;
} 
原文地址:https://www.cnblogs.com/widsom/p/7200558.html