• ZOJ 4067 Books (2018icpc青岛J) (贪心)


    题意

    给你一个长度为n的数组,代表每一个物品的价格。你有一个初始钱数(x),采用以下方法贪心:
    (1)(n)扫一遍,如果(x)不比(a[i])小,就买下它,买不起就跳过。
    给你最终买的物品数量m,求(x)的最大值。

    思路

    我队的贪心菜的一笔,果然我也有很大的责任。。
    首先如果最后全部买完,那么刚开始的钱一定是无穷多的。
    我们先假设数组里没有0,那么通过题意中的贪心方法,最后买的一定是前m个
    证明:
    (m=0)的时候,显然成立。
    假设当(m=i)的时候成立,即已经连续买了前(i)个。
    买第(i+1)个的时候,如果不买(a[i+1]),而买了(a[j])(j>i+1):
    ①当(a[i+1]leq a[j])时,由于题意中的贪心,如果买了(a[j]),对于(j>i+1),且(a[j]geq a[i+1])时,(a[i+1])是必买的,所以不成立
    ②当(a[i+1]>a[j])时,由于两个位置对m的贡献都为1,为使答案最大,还是要选最大的(a[i+1])
    综上所述,此时要买(a[i+1])
    再综上所述,最后买的一定是前m个
    所以,没有0的时候,我们直接买前m个即可
    当数组里是有0时,因为永远可以买0,所以要从m里减去0的个数,然后对剩下的数做上述算法
    当然如果0的个数本身就超过(m),就是(impossible)的。

    代码

    注释提供了一些假算法的插点

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
        
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x)) 
    
    using namespace std;
    
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
    
    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 3e6+100;
    const int maxm = 2e6+100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);
    
    int n,m;
    ll a[maxn];
    int cnt;
    ll sum[maxn];
    multiset<ll>s;
    int main() {
        int t;
        scanf("%d", &t);
        while(t--){
            cnt=0;
            scanf("%d %d", &n, &m);
            for(int i = 1; i <= n; i++){
                scanf("%lld", &a[i]);
                if(!a[i])cnt++;
            }
            if(n==m){
                printf("Richman
    ");continue;
            }
            if(cnt>m){
                printf("Impossible
    ");continue;
            }
            ll ans=0;
            m-=cnt;
            int p = 0;
            int num=0;
            for(int i = 1; i <= n&&num<m; i++){
                if(a[i]){ans+=a[i];p=max(p,i);num++;}
            }
            //printf("  %d
    ",p);
            ll mi = 0x7f7f7f7f7f7f7f7f;
            for(int i = p+1; i <= n; i++){
                if(a[i])mi=min(mi,a[i]);
            }
            if(mi==0x7f7f7f7f7f7f7f7f){
                printf("Richman
    ");continue;
            }
            printf("%lld
    ",mi-1+ans);
        }
        return 0;
    }
    /*
    2
    7 6
    4 1 0 3 0 0 1
    6 5
    4 5 0 3 0 0
    
     */
    
  • 相关阅读:
    【C语言基础】解决C语言error: expected ‘;‘, ‘,‘ or ‘)‘ before ‘&‘ token
    【ubuntu基础】ubuntu terminal shortcut
    【CV项目调试】darknet源码中CUDNN_CONVOLUTION_FWD_SPECIFY_WORKSPACE_LIMIT问题
    【linux基础】linux 多个会话同时执行命令后history记录不全的解决方案
    【DL基础】激活函数总结
    【shell基础】判断目录是否为空
    【socketCAN错误】write: No buffer space available
    【DL基础】损失函数总结
    【CV源码实现及调试】darknet中opencv的问题
    【开源库STBI基础】STBI图像库的理解
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/11560174.html
Copyright © 2020-2023  润新知