zoukankan      html  css  js  c++  java
  • POJ 1787 Charlie's Change (多重背包 带结果组成)

    题意:求通过c1个1分的c2个5分的c3个10分的c4个25分的组成p的最多个数并且输出分别选多少个。

    分析:多重背包+一个数组保存当前最优解情况下选的个数;

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <cmath>
    #include <cstdlib>
    #include <map>
    #include <vector>
    
    using namespace std;
    
    const int oo = 1e8;
    
    struct C
    {
        int x, num;
    }c[120];
    
    void Init(int c1, int x, int &k)
    {
        int num = 1;
        while(c1>=num)
        {
            c[k].x = num*x;
            c[k++].num = num;
            c1-=num;
            num*=2;
        }
        if(c1!=0)
        {
            c[k].x = c1*x;
            c[k++].num = c1;
        }
    }
    
    bool cmp(C x1, C x2)
    {
        return x1.x < x2.x;
    }
    int dp[10005];
    int ans[10005][6];
    
    int main()
    {
        int p, c1, c2, c3, c4;
        while(scanf("%d %d %d %d %d", &p, &c1, &c2, &c3, &c4), p+c1+c2+c3+c4)
        {
            int k = 0;
            Init(c1, 1, k);
            Init(c2, 5, k);
            Init(c3, 10, k);
            Init(c4, 25, k);
            sort(c, c+k, cmp);
            memset(dp, 0, sizeof(dp));
            memset(ans, 0, sizeof(ans));
            dp[0] = 1;
            for(int i=0; i<k; i++)
            {
                for(int j=p; j>=c[i].x; j--)
                {
                    if(dp[j-c[i].x]&&dp[j-c[i].x]+c[i].num > dp[j])
                    {
                        dp[j] = dp[j-c[i].x]+c[i].num;
                        int x = c[i].x/c[i].num;
                        if(x==1)
                        {
                            ans[j][1] = ans[j-c[i].x][1]+c[i].num;
                            ans[j][2] = ans[j-c[i].x][2];
                            ans[j][3] = ans[j-c[i].x][3];
                            ans[j][4] = ans[j-c[i].x][4];
                        }
                        else if(x==5)
                        {
                            ans[j][2] = ans[j-c[i].x][2]+c[i].num;
                            ans[j][1] = ans[j-c[i].x][1];
                            ans[j][3] = ans[j-c[i].x][3];
                            ans[j][4] = ans[j-c[i].x][4];
                        }
                        else if(x==10)
                        {
                            ans[j][3] = ans[j-c[i].x][3]+c[i].num;
                            ans[j][2] = ans[j-c[i].x][2];
                            ans[j][1] = ans[j-c[i].x][1];
                            ans[j][4] = ans[j-c[i].x][4];
                        }
                        else
                        {
                            ans[j][4] = ans[j-c[i].x][4]+c[i].num;
                            ans[j][2] = ans[j-c[i].x][2];
                            ans[j][3] = ans[j-c[i].x][3];
                            ans[j][1] = ans[j-c[i].x][1];
                        }
                    }
                }
            }
            if(dp[p]==0)
                printf("Charlie cannot buy coffee.
    ");
            else
                printf("Throw in %d cents, %d nickels, %d dimes, and %d quarters.
    ",
                       ans[p][1], ans[p][2], ans[p][3], ans[p][4]);
        }
    
        return 0;
    }
  • 相关阅读:
    1.2 C++命名空间(namespace)
    1.3 C++引用(Reference)
    在ros功能包CMakeLists.txt中获取所在功能包的路径 便于添加第三方库的相对路径
    ubuntu14.04下搜狗输入法不能输入中文问题解决
    js对日期的判断
    Calendar用法随笔
    键盘事件
    onkeyup+onafterpaste 只能输入数字和小数点--转载
    导出数据到EXL表格中
    DENON AVR-X510BT 功放设置记录
  • 原文地址:https://www.cnblogs.com/mengzhong/p/5517576.html
Copyright © 2011-2022 走看看