Codeforces_446_B

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;
} 

 

posted @ 2016-09-14 15:00  zzzzzzzzhu  阅读(162)  评论(0编辑  收藏  举报