• Qbxt 模拟题 day3(am) T3 选数字 (select)(贪心)


    选数字 (select
    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。

    /* 
    贪心+预处理.
    处理出行和列分别选i次的最优值.
    然后行选i次,列选k-i次相加减去中间重复的. 
    一开始暴力n==1处理和这个差不多.
    暴力的时候也想处理出一些东西.
    但是想到可能会对后面有影响
    so 没处理(orz).
    然后T挺了.
    这题就是这点儿想不过来.
    以后认识问题要深刻. 
    */
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #define LL long long
    #define MAXN 1000001
    #define MAXM 1001
    using namespace std;
    LL sum[MAXN],sum1[MAXN],ans=-1e18,c[MAXM],l[MAXM],xx;
    LL n,m,k,p,g[MAXM][MAXM];
    priority_queue<long long,vector<long long> >q;
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void slove()
    {
        for(int i=1;i<=m;i++) q.push(c[i]);
        for(int i=1;i<=k;i++) xx=q.top(),sum1[i]=sum1[i-1]+xx,q.pop(),q.push(xx-n*p);
        while(!q.empty()) q.pop();
        for(int i=1;i<=n;i++) q.push(l[i]);
        for(int i=1;i<=k;i++) xx=q.top(),sum[i]=sum[i-1]+xx,q.pop(),q.push(xx-m*p);
        for(int i=0;i<=k;i++) 
        ans=max(ans,sum[i]+sum1[k-i]-i*(k-i)*p);
        return ;
    }
    int main()
    {
        freopen("select.in","r",stdin);
        freopen("select.out","w",stdout);
        n=read(),m=read(),k=read(),p=read();
        for(int i=1;i<=n;i++)
          for(int j=1;j<=m;j++)
            g[i][j]=read(),c[j]+=g[i][j],l[i]+=g[i][j];
        slove();
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    umeng社交分享最新版5.0的跨进程使用崩溃的问题及解法-Android
    AlertDialog禁止返回键
    一个男人想经商,不读 100本商人自传,怎么会了解商人的思维状态
    Android中使用Gson解析JSON数据的两种方法
    DevExpress gridControl控件动态绑定列 zt
    获得WCF Client端的本地端口 z
    log4net.dll配置以及在项目中应用 zt
    系统交易策略 hylt
    判斷作業系統為 64bit 或 32bit z
    路徑 z
  • 原文地址:https://www.cnblogs.com/nancheng58/p/10068164.html
Copyright © 2020-2023  润新知