• poj 3040 Allowance 贪心


    贪心,从大到小排序,只要不超额就能放多少就放多少,最后再从小的开始找一个放进去能超额的。

    正确性证明,因为大的是小的倍数,所以大的放进去不超额一定要放进去,因为小的不管怎么取,再超过c之前一定会凑成这个大的面额,那么用大的代替一定更优。

    第一步做完之后,那么现在一定要再放进去一个硬币,那么选择最小的并且能大于c的也一定是最优的。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=22;
    int need[maxn];
    struct C
    {
        int v,b;
        bool operator <(const C & xx) const
        {
            return v>xx.v;
        }
    }coin[maxn];
    
    int main()
    {
        int n,c;
        while(scanf("%d %d",&n,&c)!=EOF)
        {
            for(int i=1;i<=n;i++)
            scanf("%d %d",&coin[i].v,&coin[i].b);
            sort(coin+1,coin+1+n);
            int ans=0;
            while(1)
            {
                memset(need,0,sizeof(need));
                int sum=c;
                for(int i=1;i<=n;i++)
                {
                    int tmp=sum/coin[i].v;
                    tmp=min(coin[i].b,tmp);
                    need[i]=tmp;
                    sum-=tmp*coin[i].v;
                }
                if(sum>0)
                for(int i=n;i>=1;i--)
                if(coin[i].b&&coin[i].v>=sum)
                {
                    need[i]++;
                    sum=0;
                    break;
                }
                if(sum>0) break;
                int minm=2e9;
                for(int i=1;i<=n;i++)
                if(need[i])
                minm=min(coin[i].b/need[i],minm);
                ans+=minm;
                for(int i=1;i<=n;i++)
                if(need[i])
                coin[i].b-=need[i]*minm;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    


  • 相关阅读:
    [摘]MongoDB范围查询的索引优化
    python ftp 暴破
    写mongodb日志
    [转]使用 Python 实现跨平台的安装程序
    HDOJ 1008 Elevator
    第一个数字
    反转串
    HDOJ 1108 最小公倍数
    HDOJ 1096 A+B for InputOutput Practice (VIII)
    报数游戏
  • 原文地址:https://www.cnblogs.com/pangblog/p/3303859.html
Copyright © 2020-2023  润新知