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;
    }
  • 相关阅读:
    Python 3: 加密简介
    5 个最受人喜爱的开源 Django 包
    ROS tf-增加坐标系
    ROS tf监听编写
    ROS tf广播编写
    ROS tf基础使用知识
    ROS tf-数据类型
    Windows Vistual Studio 2013/2015 MRPT安装
    OMPL 在windows下的安装
    CMake 设置Target输出目录和后缀名
  • 原文地址:https://www.cnblogs.com/mengzhong/p/5517576.html
Copyright © 2011-2022 走看看