选数字 (select)

37 篇文章 1 订阅

Time Limit:3000ms Memory Limit:64MB

题目描述

LYK 找到了一个 n*m 的矩阵,这个矩阵上都填有一些数字,对于第 i 行第 j 列的位置上

的数为 ai,j。

由于它 AK 了 noip2016 的初赛,最近显得非常无聊,便想到了一个方法自娱自乐一番。

它想到的游戏是这样的:每次选择一行或者一列,它得到的快乐值将会是这一行或者一列的

数字之和。之后它将该行或者该列上的数字都减去 p(之后可能变成负数)。如此,重复 k

次,它得到的快乐值之和将会是它 NOIP2016 复赛比赛时的 RP 值。

LYK 当然想让它的 RP 值尽可能高,于是它来求助于你。

输入格式(select.in)

第一行 4 个数 n,m,k,p。

接下来 n 行 m 列,表示 ai,j。

输出格式(select.out)

输出一行表示最大 RP 值。

输入样例

2 2 5 2

1 3

2 4

输出样例

11

数据范围 总共 10 组数据。

对于第 1,2 组数据 n,m,k<=5。

对于第 3 组数据 k=1。 对于第 4 组数据 p=0。
对于第 5,6 组数据 n=1,m,k<=1000。

对于第 7,8 组数据 n=1,m<=1000,k<=1000000。

对于所有数据 1<=n,m<=1000,k<=1000000,1<=ai,j<=1000,0<=p<=100。

样例解释 第一次选择第二列,第二次选择第二行,第三次选择第一行,第四次选择第二行,第五

次选择第一行,快乐值为 7+4+2+0+-2=11。

贪心来做。
用两个优先队列,x[i]表示选i行最大值。y[i]表示选i列的最大值。
最后枚举选多少行多少列,并且将重叠的部分剪去。

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#define LL long long
#define K 1000009
using namespace std;
LL mx[K],my[K],p,ans,a[1009][1009];
int n,m,k;
priority_queue <LL> qh;
priority_queue <LL> ql;
int main()
{
    freopen("select.in","r",stdin);
    freopen("select.out","w",stdout);
    scanf("%d%d%d%lld",&n,&m,&k,&p);
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++) 
     {
        scanf("%lld",&a[i][j]);
        mx[i]+=a[i][j];
        my[j]+=a[i][j];
     }
    for(int i=1;i<=n;i++) qh.push(mx[i]),mx[i]=0;
    for(int i=1;i<=m;i++) ql.push(my[i]),my[i]=0;

    for(int i=1;i<=k;i++)
    {
        LL x=qh.top();
        qh.pop();
        mx[i]=mx[i-1]+x;
        qh.push(x-p*1ll*m);
    }
    for(int i=1;i<=k;i++)
    {
        LL x=ql.top();
        ql.pop();
        my[i]=my[i-1]+x;
        ql.push(x-p*1ll*n);
    }

    ans=-1e18;
    for(int i=0;i<=k;i++)//从0开始!
     ans=max(ans,mx[i]+my[k-i]-p*i*1ll*(k-i));
    printf("%lld",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值