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

題目連接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4067ios

 

題意:c++

給出 $n$ 本書(編號 $1 \sim n$),第 $i$ 本書的價格爲 $a_i$ 元。我如今手上有若干元錢,我買書的策略爲從 $1 \sim n$ 依次買書,若遇到價格不超過我手上錢數的,我就買下,不然就跳過。算法

如今已知我買了 $m$ 本書,請求出我手上最多有多少元錢。spa

 

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

 

題解:code

(這題剛開始想了個二分的假算法……WA了好多發,瘋狂演隊友,而後在我找不出任何二分哪裏錯了的絕望時刻,隊友力挽狂瀾想出了下面的思路QAQ)blog

假設我手上有 $k$ 元,我若某次在遇到書 $A$ 時跳過了而以後買了 $B$,顯然價格上 $A>B$。ci

所以我手上只有多過 $k$ 元,才能買下 $A$,從而不買 $B$。換句話說,當我一本書都不跳過的時候,纔是個人錢最多的時候。get

因此,先去掉全部價格爲 $0$ 的書,這些是白送的我確定會買。剩下來要花錢買 $m-cnt_{price=0}$ 本書,即買前 $m-cnt_{price=0}$ 本書;而後再在其他的書中找價格最低的那一本,其價格減去 $1$,加上便可。it

 

AC代碼:io

#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\n";
        else if(cnt0>m) cout<<"Impossible\n";
        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<<'\n';
        }
    }
}
相關文章
相關標籤/搜索