POJ 3260 The Fewest Coins(多重背包问题, 找零问题, 二次DP)
2013-12-08 16:52
351 查看
Q: 既是多重背包, 还是找零问题, 怎么处理?
A: 题意理解有误, 店主支付的硬币没有限制, 不占额度, 所以此题不比 1252 难多少
Description
Farmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the smallest number of coins changes hands, i.e., the number of coins he uses to pay plus the number of coins he receives in change is minimized. Help him to determine what this minimum number is.
FJ wants to buy T (1 ≤ T ≤ 10,000) cents of supplies. The currency system has N (1 ≤ N ≤ 100) different coins, with values V1, V2, ..., VN (1 ≤ Vi ≤ 120). Farmer John is carrying C1 coins of value V1, C2 coins of value V2, ...., and CN coins of value VN (0 ≤Ci ≤ 10,000). The shopkeeper has an unlimited supply of all the coins, and always makes change in the most efficient manner (although Farmer John must be sure to pay in a way that makes it possible to make the correct change).
Input
Line 1: Two space-separated integers: N and T.
Line 2: N space-separated integers, respectively V1, V2, ..., VN coins (V1, ...VN)
Line 3: N space-separated integers, respectively C1, C2, ..., CN
Output
Line 1: A line containing a single integer, the minimum number of coins involved in a payment and change-making. If it is impossible for Farmer John to pay and receive exact change, output -1.
Sample Input
Sample Output
Hint
Farmer John pays 75 cents using a 50 cents and a 25 cents coin, and receives a 5 cents coin in change, for a total of 3 coins used in the transaction.
题意:
John 去付款, 手上拿着各种面值的硬币, 每种面值的硬币有一个可以使用的上限, 店主支持找钱, 找钱所用的硬币是无限的
思路:
1. 证明背包的容量上限是个难点, 这里有个证明
http://www.cppblog.com/Davidlrzh/articles/135614.html
背包容量上限是 T + vmax^2
2. 使用倍增优化转化为 0/1 背包来做. 先求解 Jhon 的给钱方式, 再求解找钱方案, 两次 DP
3. Jhon 的状态转移方程. dp[i][j] = min(dp[i][j], dp[i][j-w[i]]+1)
店主的状态转移方程可以有两种表述, dp2[i][j] = min(dp2[i][j], dp2[i][j-w[i]]+1) (和 Jhon 的一样), 但是用到两个dp 数组
4. 第二种表述和 1252 相同, 仅使用一个dp 数组, 总的状态转移方程为 dp[j] = min([j-w[i]+1, dp[j+w[i]]+1);
总结:
1. 看别人的解题报告, 才知道店主找零的硬币是没有上限的, 这将题目的难度下降了很多, 难点就变成多重背包的优化了
2. 思路(3,4)的状态转移方程有误, 因为进行过倍增优化, 所以状态转移方程中并不是简单的+1, 而应该+倍增优化的倍数
3. 没判断输出为 INF 的情况, WA 了一次, 找到了测试用例地址
http://cerberus.delos.com:790/TESTDATA/DEC06_5.htm
代码:
A: 题意理解有误, 店主支付的硬币没有限制, 不占额度, 所以此题不比 1252 难多少
Description
Farmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the smallest number of coins changes hands, i.e., the number of coins he uses to pay plus the number of coins he receives in change is minimized. Help him to determine what this minimum number is.
FJ wants to buy T (1 ≤ T ≤ 10,000) cents of supplies. The currency system has N (1 ≤ N ≤ 100) different coins, with values V1, V2, ..., VN (1 ≤ Vi ≤ 120). Farmer John is carrying C1 coins of value V1, C2 coins of value V2, ...., and CN coins of value VN (0 ≤Ci ≤ 10,000). The shopkeeper has an unlimited supply of all the coins, and always makes change in the most efficient manner (although Farmer John must be sure to pay in a way that makes it possible to make the correct change).
Input
Line 1: Two space-separated integers: N and T.
Line 2: N space-separated integers, respectively V1, V2, ..., VN coins (V1, ...VN)
Line 3: N space-separated integers, respectively C1, C2, ..., CN
Output
Line 1: A line containing a single integer, the minimum number of coins involved in a payment and change-making. If it is impossible for Farmer John to pay and receive exact change, output -1.
Sample Input
3 70 5 25 50 5 2 1
Sample Output
3
Hint
Farmer John pays 75 cents using a 50 cents and a 25 cents coin, and receives a 5 cents coin in change, for a total of 3 coins used in the transaction.
题意:
John 去付款, 手上拿着各种面值的硬币, 每种面值的硬币有一个可以使用的上限, 店主支持找钱, 找钱所用的硬币是无限的
思路:
1. 证明背包的容量上限是个难点, 这里有个证明
http://www.cppblog.com/Davidlrzh/articles/135614.html
背包容量上限是 T + vmax^2
2. 使用倍增优化转化为 0/1 背包来做. 先求解 Jhon 的给钱方式, 再求解找钱方案, 两次 DP
3. Jhon 的状态转移方程. dp[i][j] = min(dp[i][j], dp[i][j-w[i]]+1)
店主的状态转移方程可以有两种表述, dp2[i][j] = min(dp2[i][j], dp2[i][j-w[i]]+1) (和 Jhon 的一样), 但是用到两个dp 数组
4. 第二种表述和 1252 相同, 仅使用一个dp 数组, 总的状态转移方程为 dp[j] = min([j-w[i]+1, dp[j+w[i]]+1);
总结:
1. 看别人的解题报告, 才知道店主找零的硬币是没有上限的, 这将题目的难度下降了很多, 难点就变成多重背包的优化了
2. 思路(3,4)的状态转移方程有误, 因为进行过倍增优化, 所以状态转移方程中并不是简单的+1, 而应该+倍增优化的倍数
3. 没判断输出为 INF 的情况, WA 了一次, 找到了测试用例地址
http://cerberus.delos.com:790/TESTDATA/DEC06_5.htm
代码:
#include <iostream> using namespace std; int N,T; int V[150], C[150]; int upload; int dp[100000]; int stuff[10010]; int cnt[10010]; int len; const int INF = 0X3F3F3F3F; /* * 倍增优化转成 01 背包 * 处理 01 背包, 求解 Jhon 恰好付 v 元 所需要的硬币数 */ void firstPass() { len = 0; for(int i = 0; i < N; i ++) { int rem = C[i]; int j = 0; while(rem) { // 倍增优化转化成 01 背包 if(rem >= (1<<j)) { stuff[len++] = V[i]*(1<<j); cnt[len-1] = (1<<j); rem -= (1<<j); j++; }else{ stuff[len++] = V[i]*rem; cnt[len-1] = rem; rem = 0; } } } memset(dp, 0x3f, sizeof(int)*(upload+10)); dp[0] = 0; for(int i = 0; i < len; i ++) { for(int v = upload; v >= stuff[i]; v--) { dp[v] = min(dp[v], dp[v-stuff[i]]+cnt[i]); //printf("dp[%d], stuff[%d] = %d\n", v, i, stuff[i]); } } } /* * second pass 完全背包 * 状态转移方程, dp[v] = min(dp[v], dp[v+w[i]]+1) * 要注意遍历顺序 */ int secondPass() { for(int i = 0; i < N; i ++) { for(int v = upload-V[i]; v >= 0; v --) { dp[v] = min(dp[v], dp[v+V[i]]+1); } } return dp[T]; } int main() { freopen("E:\\Copy\\ACM\\测试用例\\in.txt", "r", stdin); cin >> N >> T; int vmax = 0; int sum = 0; for(int i = 0; i < N; i ++) { scanf("%d", &V[i]); vmax = max(vmax, V[i]); } upload = vmax*vmax + T; for(int i = 0; i < N; i ++) { scanf("%d", &C[i]); sum += C[i]*V[i]; } if(sum < T) cout << -1 << endl; else { firstPass(); int ans = secondPass(); if(ans != INF) cout << secondPass() << endl; else cout << -1 << endl; } return 0; }
相关文章推荐
- POJ 1252 Euro Efficiency(完全背包, 找零问题, 二次DP)
- 0-1背包问题入门小结 动态规划(DP)经典题目 POJ324 POJ1276
- [poj 1947]树dp+背包问题
- POJ 1417 True Liars(种类并查集+dp背包问题)
- 0-1背包问题入门小结 动态规划(DP)经典题目 POJ324 POJ1276
- poj 1160 Post Office--DP--类背包问题
- 0-1背包问题入门小结 动态规划(DP)经典题目 POJ324 POJ1276
- dp中滚动数组的应用:01背包、POJ 1159 Palindrome、多段图路径问题
- poj 1947(树形dp+背包问题)
- POJ 3132 Sum of Different Primes 动态规划 DP 0-1背包问题
- Rebuilding Roads POJ - 1947 简单树形DP加背包问题
- POJ 3132 Sum of Different Primes 动态规划 DP 0-1背包问题
- POJ 2624 Charm Bracelet DP(背包问题)
- poj 1384 完全背包问题 dp
- poj 2229 (dp 完全背包相似问题)
- POJ 1742-Coins [dp 多重背包问题] 《挑战程序设计竞赛》2.3
- poj 3624 Charm Bracelet DP 0/1 背包问题
- POJ 状态DP+ 01 背包问题
- HDU 2844 Coins (多重背包问题DP)
- POJ 3624 【DP入门之01背包】