poj 1787 Charlie's Change

简介: 思路: 多重背包 分析: 1 题目给定的数据明显就是多重背包,但是题目有个难点就是输出路径,0/1背包里面有输出路经的方法,做法做法是通过记录前面的状态 2 这一题还要求输出每种硬币的个数,那么这边利用mark数组,mark[i][0] ...
思路: 多重背包
分析:
1 题目给定的数据明显就是多重背包,但是题目有个难点就是输出路径,0/1背包里面有输出路经的方法,做法做法是通过记录前面的状态
2 这一题还要求输出每种硬币的个数,那么这边利用mark数组,mark[i][0] = pos 表示的是当前这个状态是取的是第pos个物品,mark[i][pos] = x;表示的是当前这个状态增加了x个物品

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int MAXN = 10010;
const int N = 5;
const int INF = 0x3f3f3f3f;

int v[N] = {0,1,5,10,25};
int sum , num[N] , dp[MAXN];
int ans[N] , path[MAXN] , mark[MAXN][N];

void zeroOnePack(int pos , int k , int cost , int weight){
    for(int i = sum ; i >= cost ; i--){
        dp[i] = max(dp[i] , dp[i-cost]+k);
        if(dp[i] == dp[i-cost]+1){
            path[i] = i-cost;
            mark[i][0] = pos;
            mark[i][pos] = k;
        }
    }
}

void completePack(int pos , int cost , int weight){
    for(int i = cost ; i <= sum ; i++){
        dp[i] = max(dp[i] , dp[i-cost]+1);
        if(dp[i] == dp[i-cost]+1){
            path[i] = i-cost;
            mark[i][0] = pos;
            mark[i][pos] = 1;
        }
    }
}

void multiplePack(int pos , int cost,int weight,int amount){
    if(cost*amount >= sum){
        completePack(pos , cost , weight);
        return;
    }
    int k = 1;
    while(k < amount){
        zeroOnePack(pos , k , k*cost , k*weight); 
        amount -= k;
        k *= 2; 
    }
    zeroOnePack(pos , amount , amount*cost , amount*weight);
}

int main(){
    while(scanf("%d",&sum)){
        scanf("%d%d%d%d",&num[1],&num[2],&num[3],&num[4]);
        if(!(sum+num[1]+num[2]+num[3]+num[4]))
            break;
        for(int i = 0 ; i < MAXN ; i++)
            dp[i] = -INF;
        dp[0] = 0;
        for(int i = 1 ; i <= 4 ; i++)
            multiplePack(i , v[i],v[i],num[i]);
        if(dp[sum] < 0)
            puts("Charlie cannot buy coffee.");
        else{
            int pos = sum;
            memset(ans , 0 , sizeof(ans));
            while(pos){
                int tmp = mark[pos][0];
                ans[tmp] += mark[pos][tmp]; 
                pos = path[pos];
            }
            printf("Throw in %d cents, %d nickels, %d dimes, and %d quarters.\n",ans[1],ans[2],ans[3],ans[4]);
        }
    }
    return 0;
}



目录
打赏
0
0
0
0
15
分享
相关文章
uva674Coin Change
题意:手中的硬币币值有1,5,10,25,50共5种,给定一个面值n,问把n兑换成硬币的方案总数是多少。 分析:先打表,再输入输出。动态规划的简单题目,设dp[i]表示面值为i的情况下能兑换的种类,那么dp[i]=sigma(dp[i-v[j]]), j=0..4, v[j]={1,5,10,25,50};也就是,如果i大于v[j],说明能够用dp[i-v[j]]的方案再加上一枚面值为v[j]的硬币作为面值i的方案,不过这只是方案中硬币的数量多了一枚,题目中只是问方案数量,那么此时两者在方案数量上等价,那么方案总数上加上这一种情况就可以了。
735 0
uva 674Coin Change(完全背包)
点击打开链接uva 674 思路: 完全背包 分析: 裸题 代码: #include #include #include #include using namespace std; const int MAXN = 8000; ...
912 0
poj 1789 Truck History
点击打开链接poj 1789 思路:最小生成树+prime 代码: #include #include #include #include using namespace std; #define MAXN 2010 #defi...
678 0
uva 10085 10085 - The most distant state
点击打开链接 题目意思: 八数码问题的变形,给定一个初始状态要求找到该状态很够到达的最远的状态,输出这个最远状态和路径。(特判,答案不唯一) 解题思路:  做过八数码的同学肯定觉得这一题很水吧,确实是的,要求我么找到最远的,我么知道广...
1078 0
LeetCode 322. Coin Change
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
117 0
LeetCode 322. Coin Change
POJ 2492 A Bug&#39;s Life
A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 35756   Accepted: 11730 Description Background Profe...
1063 0
poj 2492 A Bug's Life
点击打开链接poj 2492 思路:带权并查集 分析: 1 用rank[i] = 0表示关系相同,用rank[i] = 1表示关系不同 2 在输入的时候把两个元素之间的关系建立起来,然后判断当前的两个元素是否在同一个集合里面,如果是则判断是不是属于同一个类型即可。
925 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等