<span style="color:#3333ff;">/*
_______________________________________________________________________________________
author : Grant yuan
time : 2014.7.21
algorithm : priority_queue
explain : 首先对行和列在1到k的范围内分别求解,然后求出一个满足i和k-i的最大值,
注意最终的结果中减去重复计算的,还有会测试大于int类型的数据。
—————————————————————————————————————————————————————————————————————————————————————————
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<functional>
using namespace std;
#define INF 999999999;
priority_queue<__int64>q1;
priority_queue<__int64>q2;
__int64 m,n,k,p,h;
__int64 a[1003][1003];
__int64 s1[1003],s2[1003];
__int64 sum1[1000003],sum2[1000003];
__int64 res,ans,hh;
int main()
{
cin>>n>>m>>k>>p;
ans=INF;
ans=-ans*ans;
memset(s1,0,sizeof(s1));
memset(s2,0,sizeof(s2));
memset(sum1,0,sizeof(sum1));
memset(sum2,0,sizeof(sum2));
while(!q1.empty())
q1.pop();
while(!q2.empty())
q2.pop();
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
scanf("%I64d",&a[i][j]);
s1[i]+=a[i][j];
s2[j]+=a[i][j];}
for(int i=0;i<n;i++)
q1.push(s1[i]);
for(int i=0;i<m;i++)
q2.push(s2[i]);
for(int i=1;i<=k;i++)
{
h=q1.top();q1.pop();
if(i==1)sum1[i]=h;
else sum1[i]=sum1[i-1]+h;
h-=m*p;
q1.push(h);
}
for(int i=1;i<=k;i++)
{
h=q2.top();q2.pop();
if(i==1)sum2[i]=h;
else sum2[i]=sum2[i-1]+h;
h-=n*p;
q2.push(h);
}
for(int i=0;i<=k;i++)
{
res=sum1[i]+sum2[k-i];
ans=max(ans,res-i*p*(k-i));
}
cout<<ans<<endl;
return 0;
}
</span>【组队赛三】-D 优先队列 cf446B,布布扣,bubuko.com
原文:http://blog.csdn.net/yuanchang_best/article/details/38022499