[Sicily Coins] 动态规划 多重背包问题
来源:互联网 发布:软件前端是什么 编辑:程序博客网 时间:2024/06/05 04:31
1. 问题描述
Description
Ouyang has 6 kinds of coins.
The number of the i-th coin is A[i] (0<=i<6).
Their value and weight are as follewed:
0. $0.01, 3g
1. $0.05, 5g
2. $0.10, 2g
3. $0.25, 6g
4. $0.50, 11g
5. $1, 8g
Ouyang want to run away from home with his coins.
But he is so weak that he can only carry M gram of coins.
Given the number of each coin he has, what is the maximal value of coins he can take?
Input
There are multiple cases.
Each case has one line with 7 integers: M (1<=M<=10000), A[i], (0<=i<6, 0<=A[i]<=100000).
Output
The maximal value of coins he can take.
Sample Input
1 1 1 1 1 1 1
38 3 1 10 4 2 1
75 8 5 23 4 2 4
Sample Output
$0.00
$2.40
$6.10
2. 基本思路
回顾:0-1背包问题
- 在0-1背包问题中,给定n个物品,第i个物品有重量w[i]和价值v[i],用容量为W的背包来装物品,总价值最大是多少?
- OPT(i, w)表示:背包容量为w时,考虑给定第1, 2, …, i个物品,能取得的最大价值。装物品的时候有以下两种情况:第一种情况是不选择第i个物品,那么最大价值将会是:容量为w,考虑物品{1, 2, …, i-1}所取得的价值;第二种情况是选择第i个物品,那么最大价值将会是:容量为(w-w[i]),考虑物品{1, 2, …, i-1}所取得的价值加上当前第i个物品的价值v[i]。
- 0-1背包问题的代码实现如下 :
for (int w = 0; w <= W; w++){ M[0, w] = 0;}for (int i = 1; i <= n; i++){ for (w = 1; w <= W; w++) { if (wt[i] > w) { M[i, w] = M[i - 1, w]; } else { M[i, w] = max(M[i - 1][w], v[i] + M[i - 1, w - wt[i]]); } }}
多重背包问题
- 以上的Coins问题属于多重背包问题。多重背包问题与0-1背包问题的不同之处在于:多重背包问题每种类型的物品可以有多个。
- 在0-1背包的基础上加入以下内容即可实现:
M[i][w] = 0;int nCount = min(A[i], w / wt[i]);for(int k = 0; k <= nCount; k++){ M[i][w] = max(M[i][w], k * value[i] + M[i - 1][w - k * wt[i]]);}
- nCount记录的是当前的第i种物品最多可以放多少个,受两个因素限制,第一个因素是一共有A[i]个类型i的物品,第二个因素是背包容量为w,最多能装(w / wt[i])个,取这两个数中较小的一个作为nCount。
- 接着尝试放0到nCount个类型i的物品到背包。k等于多少就等于放多少个类型i的物品进去。
- M[i][w]取的是M[i][w]和(k * value[i] + M[i - 1][w - k * wt[i]])中的最大值,这样才能更新M[i][w]。
- 对于固定的i和w,M[i][w]并不是随着k的增大而增大的,有时候你可以选择不装这么多类型i的物品,留些容量装前面类型的物品,可能会使得总价值更大。
3. 代码实现
#include<iostream>#include<iomanip> using namespace std;int A[7];double value[7] = {0, 0.01, 0.05, 0.10, 0.25, 0.50, 1.0};int wt[7] = {0, 3, 5, 2, 6, 11, 8};double M[10][11000] = {0};int main(){ int W; while(cin >> W) { A[0] = 0; for(int i = 1; i <= 6; i++) cin >> A[i]; for(int w = 0; w <= W; w++) M[0][w] = 0; for(int i = 0; i <= 6; i++) M[i][0] = 0; for(int i = 1; i <= 6; i++) { for(int w = 1; w <= W; w++) { M[i][w] = 0; int nCount = min(A[i], w / wt[i]); for(int k = 0; k <= nCount; k++) { M[i][w] = max(M[i][w], k * value[i] + M[i - 1][w - k * wt[i]]); //注意这里是取的是M[i][w]和(k * value[i] + M[i - 1][w - k * wt[i]])中的最大值,而不是M[i - 1][w]和(k * value[i] + M[i - 1][w - k * wt[i]])中的最大值。 } } } cout << "$" << fixed << setprecision(2) << M[6][W] << endl; } return 0;}
0 0
- [Sicily Coins] 动态规划 多重背包问题
- poj1742 Coins 动态规划 多重背包 待补完
- 动态规划--多重背包--hdu2844 coins
- 挑战练习题2.3动态规划 poj1742 Coins 多重背包
- 动态规划:HDU2844-Coins(多重背包的二进制优化)
- 动态规划-----背包问题-----01背包,完全背包,多重背包
- poj1014 Dividing 动态规划 多重背包问题
- 动态规划-多重背包问题-二进制转换
- Coins(poj1742)动态规划+挑战多重部分和问题
- HDU Coins 【多重背包问题】
- POJ 3260 The Fewest Coins(动态规划+多重背包+完全背包)
- PAT 1068. Find More Coins (30)(背包问题,动态规划)
- 动态规划(多重背包)
- 多重背包(动态规划)
- poj 1742 Coins(多重背包可行性问题)
- poj 1742 Coins (多重背包可行性问题)
- poj-1742 COINS(多重背包问题)
- hdu 2844 Coins (多重背包问题)
- mysql 阿里开源Mysql分布式中间件:Cobar
- Jenkins创建项目
- EditText的方法及使用
- 每天一个 linux 命令(14):head 命令---学习笔记
- JS去掉输入框的左右空格
- [Sicily Coins] 动态规划 多重背包问题
- JavaScript原生代码编写选项卡Tab页跳转功能
- Eclipse tomcat启动web项目 报错 Removing obsolete files from server..Could not clean server ...
- Mysql数据库实时查看执行的sql语句
- cookie与session的区别
- java中如何用Quartz框架来实现定时任务(一)
- Android学习之友盟开发这些坑
- [图像]Canny检测的Matlab实现(含代码)
- C++ 函数原型