码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces 446B DZY Loves Modification

时间:2014-07-16 11:39:28      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:codeforces   想法   贪心   

题意:

k次操作  每次选择一行或一列  得到所选数字的和  并将所选数字同时减去p  问最多得到多少


思路:

重点在消除行列间的相互影响

由于每选一行所有列所对应的和都会-p  那么如果选了i次行  则列会-i*p  同理选列

那么影响就可以这样表示 -p*i*(k-i)  把影响提出来  这样行列就不影响了

对于行或列  单独处理时相当于一维的东西  贪心即可


代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define N 1010
#define M 1000010
typedef __int64 ll;

ll sum[2][N];
ll res[2][M];
ll ans,p;
int n,m,k;
struct node
{
    ll val;
    int x;
    bool operator<(const node fa) const
    {
        return val<fa.val;
    }
}u;
priority_queue<node> q;

int main()
{
    int i,j;
    ll w;
    scanf("%d%d%d%I64d",&n,&m,&k,&p);
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            scanf("%I64d",&w);
            sum[0][i]+=w;
            sum[1][j]+=w;
        }
    }
    while(!q.empty()) q.pop();
    for(i=1;i<=n;i++)
    {
        u.x=i;
        u.val=sum[0][i];
        q.push(u);
    }
    for(i=1;i<=k;i++)
    {
        u=q.top();
        q.pop();
        res[0][i]=res[0][i-1]+u.val;
        u.val-=p*m;
        q.push(u);
    }
    while(!q.empty()) q.pop();
    for(i=1;i<=m;i++)
    {
        u.x=i;
        u.val=sum[1][i];
        q.push(u);
    }
    for(i=1;i<=k;i++)
    {
        u=q.top();
        q.pop();
        res[1][i]=res[1][i-1]+u.val;
        u.val-=p*n;
        q.push(u);
    }
    ans=max(res[0][0]+res[1][k],res[0][k]+res[1][0]);  // hang or lie
    for(i=1;i<k;i++) ans=max(ans,res[0][i]+res[1][k-i]-p*i*(k-i));
    printf("%I64d\n",ans);
    return 0;
}


CodeForces 446B DZY Loves Modification,布布扣,bubuko.com

CodeForces 446B DZY Loves Modification

标签:codeforces   想法   贪心   

原文地址:http://blog.csdn.net/houserabbit/article/details/37822015

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!