FZU 1432 Problem 1432 Coin Changing(多重背包变形DP)
2016-11-17 22:49
302 查看
![](http://acm.fzu.edu.cn/image/problem.gif)
Problem 1432 Coin Changing
Accept: 358 Submit: 1017
Time Limit: 1000 mSec Memory Limit : 32768 KB
![](http://acm.fzu.edu.cn/image/prodesc.gif)
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.
![](http://acm.fzu.edu.cn/image/prodesc.gif)
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 kindrespectively. The last line of each case contains an integer m (1<=m<=20001) representing the given amount of money you have to exchange.
![](http://acm.fzu.edu.cn/image/prodesc.gif)
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.
![](http://acm.fzu.edu.cn/image/prodesc.gif)
Sample Input
31 32 35 318
![](http://acm.fzu.edu.cn/image/prodesc.gif)
Sample Output
5
![](http://acm.fzu.edu.cn/image/prodesc.gif)
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; }
相关文章推荐
- FZU 2218 Simple String Problem (状压DP解决集合不相同元素问题)
- hiho 1601 背包DP乱搞 [Offer收割]编程练习赛29 Problem C 最大得分
- Problem 31 Coin sums(完全背包dp)
- FZU 2218 Simple String Problem(状压DP)
- Fzu Problem 2253 Salty Fish(dp)
- FZU 2218 Simple String Problem(状压DP)
- [杂题 背包DP] Codeforces 793E Tinkoff Challenge - Elimination Round E. Problem of offices
- 西南交通大学第十三届ACM决赛 D.Music Problem 背包DP
- 西南交通大学第十三届ACM决赛 D.Music Problem 背包DP
- 计蒜客 The Heaviest Non-decreasing Subsequence Problem dp LIS变形 || 线段树+dp
- BNU 11993 Soccer Teams (01背包变形+数位dp)
- DP 动态规划 Problem R 1018 完全背包
- FZU 2253 DP(最大子段和变形)
- hdu 2041 超级楼梯(简单dp 0/1背包变形)
- FZU 2214 Knapsack problem【DP】【超大容量背包】
- 西南交通大学第十三届ACM决赛 D.Music Problem 背包DP
- 西南交通大学第十三届ACM决赛 D.Music Problem 背包DP
- 西南交通大学第十三届ACM决赛 D.Music Problem 背包DP
- 西南交通大学第十三届ACM决赛 D.Music Problem 背包DP
- DP 动态规划 Problem V 1022 反向考虑的背包