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

ZOJ4067 Books(贪心)

时间:2018-11-11 23:32:55      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:type   const   books   --   print   分享   传送门   can   font   

题目链接:传送门

题目大意:

  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\n");
            continue;
        }
        if(cnt0>m)
        {
            printf("Impossible\n");
            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\n",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(贪心)

标签:type   const   books   --   print   分享   传送门   can   font   

原文地址:https://www.cnblogs.com/Lubixiaosi-Zhaocao/p/9941710.html

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