ZOJ4067 Books(贪心)

Posted lubixiaosi-zhaocao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ4067 Books(贪心)相关的知识,希望对你有一定的参考价值。

题目链接:传送门

题目大意:

  DG在书店买书,从左到右第i本书价格为ai。DG从左走到右,能买就买。如果已知DG买了m本书,问他原本最多有多少钱。若无上限,输出“Richman”,若不可能买这么多书,输出“Impossible”。

  (偷偷diss队友想了个假二分)

  1 ≤ n ≤ 105,0 ≤ m ≤ n,0 ≤ ai ≤ 109

思路:

  ①:所有的价格为0的书DG必买,m -= cnt0。(这时若 m < 0,那就Impossible了)

  ②:DG从左走到右买书时,他在持有金额最多的情况下买的书只能是前面的m本书。

    反证:假设DG已经买掉了钱m-1本书,接着如果他买不起第m本书,而买了第m+1本书,那么am > am+1,而在DG买得起第m本书的时候他会更有钱,这与持有金额最多的条件矛盾。

  综上:DG最多的金额是前m本非0的书的总价格+剩下的非0的书中的价格最小值-1。

代码:

技术分享图片
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int n,m;
ll a[maxn];
int judge(ll k)
{
    int res=0;
    for(int i=1;i<=n;i++) {
        if(k>=a[i]) res++, k-=a[i];
    }
    return res;
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        scanf("%d%d",&n,&m);

        int cnt0=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            if(a[i]==0) cnt0++;
        }
        if(n<=m)
        {
            printf("Richman
");
            continue;
        }
        if(cnt0>m)
        {
            printf("Impossible
");
            continue;
        }

        m -= cnt0;
        ll ans=0;
        int i;
        for (i = 1; i <= n; i++) {
            if (m == 0)
                break;
            if (a[i] == 0)
                continue;
            ans += a[i];
            m--;
        }
        ll mn=0x3f3f3f3f;
        for(;i<=n;i++) if(a[i]!=0) mn=min(mn,a[i]);
        printf("%lld
",ans+mn-1);
    }
}
/*
444
4 2
1 2 4 8
4 0
100 99 98 97
2 2
10000 10000
5 3
0 0 0 0 1
4 1
4 1 3 2
4 2
100 99 0 0
*/
View Code

 

  

以上是关于ZOJ4067 Books(贪心)的主要内容,如果未能解决你的问题,请参考以下文章

Random Maze HDU - 4067(预定义状态建边(贪心建边))

2018ICPC青岛现场赛 重现训练

ZOJ - 3715贪心

ZOJ 3689 Digging(贪心+dp)

zoj 3963 Heap Partition(贪心)

UVA10670 POJ1907 ZOJ2372 Work Reduction贪心