zoukankan      html  css  js  c++  java
  • 贪心-poj-3040-Allowance

    题目链接:

    http://poj.org/problem?id=3040

    题目意思:

    有n种(n<=20)面额的硬币,每种硬币面值能整除比它大的面值。给一个c,告诉每种硬币的面值和数量,求最多能够凑多少个c.

    解题思路:

    贪心。

    对面值从大到下排序,当面值v>=c时,直接加上该种面值的数量一种就够了。

    对于v<c的,从大到小,再不超过c的情况下,能装多少装多少,剩下的如果不为0,则从小到大,找到第一个>=left.

    贪心原理:由于面值小的是面值大的的约数,在能够用面值大的时,如果用小的,就要用多个小的,而且还不能保证能凑到面值大的,可能更大。这样选择面值大的优。

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<sstream>
    #include<cstdlib>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<stack>
    #include<list>
    #include<queue>
    #include<ctime>
    #include<bitset>
    #define eps 1e-6
    #define INF 0x3f3f3f3f
    #define PI acos(-1.0)
    #define ll __int64
    #define LL long long
    #define lson l,m,(rt<<1)
    #define rson m+1,r,(rt<<1)|1
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    
    struct Inf
    {
        int v,num;
    }inf[22];
    
    int need[22];
    int n,c;
    
    bool cmp(struct Inf a,struct Inf b)
    {
        return a.v>b.v;
    }
    
    int main()
    {
       while(~scanf("%d%d",&n,&c))
       {
           for(int i=1;i<=n;i++)
               scanf("%d%d",&inf[i].v,&inf[i].num);
    
            sort(inf+1,inf+n+1,cmp);
            int ans=0;
            while(true)
            {
                memset(need,0,sizeof(need));
                int sum=c;
                for(int j=1;j<=n;j++)
                {
                    int tmp=sum/inf[j].v;
                    tmp=min(tmp,inf[j].num);
                    need[j]+=tmp; //需要这么多个
                    sum-=tmp*inf[j].v; //还剩下的
                }
                if(sum>0) //不能恰好凑齐,用一个满足的最小的补
                {
                    for(int j=n;j>=1;j--)
                    {
                        if(inf[j].num-need[j]&&inf[j].v>=sum)
                        {
                            need[j]++;
                            sum=0;
                            break;
                        }
                    }
                }
                if(sum>0) //再也凑不到了
                    break;
                int Min=INF;
                for(int j=1;j<=n;j++)//找到能够凑c的最多次数
                    if(need[j])
                        Min=min(Min,inf[j].num/need[j]);
                ans+=Min;
                for(int j=1;j<=n;j++) //减去个数
                    inf[j].num-=Min*need[j];
            }
            printf("%d
    ",ans);
       }
       return 0;
    }
    


  • 相关阅读:
    VMware ESXi 和 VMware Server 有区别
    安装源与清除缓存
    pip install --upgrade pip
    Linux/Centos查看进程占用内存大小的几种方法总结
    top命令经常用来监控linux的系统状况,比如cpu、内存的使用,程序员基本都知道这个命令。 按 q 退出
    Centos 查看 CPU 核数 和 型号 和 主频
    Docker 运行ELK日志监测系统,汉化Kibana界面
    elasticsearch启动时遇到的错误
    kubernetes 创建超级管理员和密匙
    第七章 AOP(待续)
  • 原文地址:https://www.cnblogs.com/pangblog/p/3347858.html
Copyright © 2011-2022 走看看