zoukankan      html  css  js  c++  java
  • ZOJ 4067

    题目链接: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<<'
    ';
            }
        }
    }
  • 相关阅读:
    b_lc_第k个排列(暴搜 / 数学剪枝)
    sql语句大全(2)
    经典SQL语句大全
    存储过程格式
    经典SQL语句大全(实例)非常不错的和excel等文档实例结合的sql
    触发器MSSQL常用操作
    最好的C#学习网站
    C# 反射入门知识
    MSSQL经典语句
    一些很酷的.Net技巧
  • 原文地址:https://www.cnblogs.com/dilthey/p/9941016.html
Copyright © 2011-2022 走看看