ZOJ 4067 - Books - [贪心][2018 ACM-ICPC Asia Qingdao Regional Problem J]

Posted dilthey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ 4067 - Books - [贪心][2018 ACM-ICPC Asia Qingdao Regional Problem J]相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4067

 

题意:

给出 $n$ 本书(编号 $1 sim n$),第 $i$ 本书的价格为 $a_i$ 元。我现在手上有若干元钱,我买书的策略为从 $1 sim n$ 依次买书,若遇到价格不超过我手上钱数的,我就买下,否则就跳过。

现在已知我买了 $m$ 本书,请求出我手上最多有多少元钱。

 

技术分享图片

Sample Input

4
4 2
1 2 4 8
4 0
100 99 98 97
2 2
10000 10000
5 3
0 0 0 0 1

Sample Output

6
96
Richman
Impossible

 

题解:

(这题刚开始想了个二分的假算法……WA了好多发,疯狂演队友,然后在我找不出任何二分哪里错了的绝望时刻,队友力挽狂澜想出了下面的思路QAQ)

假设我手上有 $k$ 元,我若某次在遇到书 $A$ 时跳过了而之后买了 $B$,显然价格上 $A>B$。

因此我手上只有多过 $k$ 元,才能买下 $A$,从而不买 $B$。换句话说,当我一本书都不跳过的时候,才是我的钱最多的时候。

所以,先去掉所有价格为 $0$ 的书,这些是白送的我肯定会买。剩下来要花钱买 $m-cnt_{price=0}$ 本书,即买前 $m-cnt_{price=0}$ 本书;然后再在其余的书中找价格最低的那一本,其价格减去 $1$,加上即可。

 

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int n,m;
ll a[maxn];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n>>m;
        int cnt0=0;
        for(int i=1;i<=n;i++) cin>>a[i], cnt0+=(a[i]==0);
        if(n<=m) cout<<"Richman
";
        else if(cnt0>m) cout<<"Impossible
";
        else
        {
            m-=cnt0;
            ll mn=0x3f3f3f3f, ans=0;
            for(int i=1;i<=n;i++)
            {
                if(a[i]==0) continue;
                if(m) ans+=a[i], m--;
                else mn=min(mn,a[i]);
            }
            cout<<ans+mn-1<<
;
        }
    }
}

 

以上是关于ZOJ 4067 - Books - [贪心][2018 ACM-ICPC Asia Qingdao Regional Problem J]的主要内容,如果未能解决你的问题,请参考以下文章

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

2018ICPC青岛现场赛 重现训练

ZOJ - 3715贪心

ZOJ 3689 Digging(贪心+dp)

zoj 3963 Heap Partition(贪心)

UVA10670 POJ1907 ZOJ2372 Work Reduction贪心