FZU 1432 Problem 1432 Coin Changing(多重背包变形DP)

    xiaoxiao2021-08-16  116

     Problem 1432 Coin Changing

    Accept: 358    Submit: 1017 Time Limit: 1000 mSec    Memory Limit : 32768 KB

     Problem Description

    There are n kinds of coins. Given the available number of coins for each kind, you are to calculate the minimal number of coins needed to exchange m yuan. 

     Input

    There are several test cases. The fist line of each case contains an integer n (1<=n<=10). Followed n lines, each line contains two integers representing the cost and the available number of coins of this kind respectively. The last line of each case contains an integer m (1<=m<=20001) representing the given amount of money you have to exchange. 

     Output

    Please output the minimal number of coins needed to exchange the money. If you can't exchange the given amount of money, please output -1.

     Sample Input

    31 32 35 318

     Sample Output

    5

     Source

    FZU 2006 Summer Training II 再来看看FZU 1432 题目大意:给你几种硬币,问用这些硬币换成一定金额,求最少用多少硬币能够换成. 例如: 1 3 2 3 5 3 这三种面额的硬币,要换成18. 则最优解是,5*3+2*1+1*1    需要5枚硬币 思路: 同样可以将其转化成背包问题.但是要求的并不是最大价值,而是达到背包容量,但是却使用的件数最少。 所以递推式应该变化.相应的dp初始值也需要变化。 dp[j] = min(dp[j], dp[j-w[i]]+v[i]); 这里的v[i]也就变成了用的硬币个数,w就是硬币的价值,换成背包问题就是  w就是重量,v就是价值,这道题目要求背包装满,要价值最小,所以状态转移就是上面那个了;很巧妙的用到了背包的方式。。。数据量比较大,所以用二进制

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; const int maxn = 3e4 + 5; const int INF = 1e9; int v[maxn], dp[maxn], w[maxn]; int main() { int n, m; while(~scanf("%d", &n)) { int a, b, index = 1; for(int i = 1; i <= n; i++) { scanf("%d%d", &a, &b); for(int j = 1; j <= b; j <<= 1) { w[index] = j * a; v[index++] = j; b -= j; } if(b) { w[index] = b * a; v[index++] = b; //这里记录的是多少个硬币 } } scanf("%d", &m); for(int i = 1; i <= m; i++) dp[i] = INF; //因为求最小值,所以要把其余的变成+无穷 dp[0] = 0; //0为0,这样后面的不是正无穷的说明是“填满的”,这种初始化方式有许多变通的 for(int i = 1; i < index; i++) { for(int j = m; j >= w[i]; j--) { dp[j] = min(dp[j], dp[j-w[i]]+v[i]); } } if(dp[m] != INF) //能装满说明就可以换成 printf("%d\n", dp[m]); else printf("-1\n"); } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-676477.html

    最新回复(0)