0-1 背包问题——动态规划
来源:互联网 发布:本机mac地址怎么查 编辑:程序博客网 时间:2024/06/04 22:46
0-1背包问题:
有N件商品和一个容量为V的背包。第 i 件商品的容量为c[i],价值时w[i]。求解将那些物品装入背包可使这些物品的费用总和不超过背包容量, 其价值总和最大。
问题特点:每种物品只有一件,可以选择放或者不放。
算法基本思想
利用动态规划,子问题为:f[i][v]表示前 i 件物品恰恰放入一个(剩余容量)容量为 v 的背包可以获得的最大价值。
其状态转移方程为:f[i][v] = max{ f[i-1][v], f[i-1][v-c[i]] + w[i]}
解释:“将前 i 件商品放入容量为 v 的背包中” 这个子问题,如果只考虑第 i 件商品放或者不放,那么就可以转化为只涉及前 i-1件物品的问题。即 (1)如果不放第 i 件物品,则问题转化为“前 i-1件物品放入容量为v的背包中”;(2)如果放第 i 将物品,则问题转换为 “前 i-1 件物品放入剩下的容量为v-c[i]的背包中”(此时可能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第 i 件物品获得的价值w[i]).则f[i][v]的值就是 (1)(2)中的最大值。
注:f[i][v]有意义当且仅当存在一个前 i 件物品的子集, 其费用总和为v。所以,按照这个方程地推完毕后,最优的答案不一定时f[N][V],而是f[N][0..V]的最大值。
详见http://www.cnblogs.com/zlcxbb/p/5820666.html
代码例子:
#include <iostream>using namespace std;//***********************常量定义*****************************const int MAX_NUM = 3500;const int MAX_WEIGHT = 14000;//*********************自定义数据结构*************************//********************题目描述中的变量************************int weight[MAX_NUM];int value[MAX_NUM];//**********************算法中的变量**************************//进行空间压缩,使用一维数组//dp【i】数组存放背包容量为i时,存放的最大价值//函数从第一个商品开始,一个一个放入背包,并不断修改dp数组的值int dp[MAX_WEIGHT];//***********************算法实现*****************************void Solve( int n, int w ){ for( int i=1; i<=n; i++ ) { //因为使用了一维数组,所有j要按照递减顺序 for( int j=w; j>=weight[i]; j-- ) { if( dp[j-weight[i]] + value[i] > dp[j] ) dp[j] = dp[j-weight[i]] + value[i];// cout << dp[j] << "j=" << j << "i = " << i << endl; } } cout << dp[w] << endl;}//************************main函数****************************//输入 n 商品个数;背包容量 w// Weight[i] value[i]//输出背包容量为 w 时的最大价值//例如:3 50 10 60 20 100 30 120//输出 220int main(){ //freopen( "in.txt", "r", stdin ); int n, w; cin >> n >> w; //n为商品个数,w为背包容量 for( int i=1; i<=n; i++ ) { cin >> weight[i] >> value[i]; } Solve( n, w ); return 0;}
0-1背包一维数组实现和二维数组实现的区别:
#include<iostream>#include <vector>#include <string.h>using namespace std;void oneArray(int n, int w, int weight[], int value[]);void twoArray(int n, int w, int weight[], int value[]);int main(){ int n = 3, w = 50; int weight[n+1] = {0,10,20,30}; int value[n+1] {0,60,100,120};// oneArray(n, w, weight, value); twoArray(n, w, weight, value); return 0;}//一维数组void oneArray(int n, int w, int weight[], int value[]){ int dp[w+1] = {0}; for (int i = 1; i <= n; ++i) { for (int j = w; j >= weight[i]; --j) { if (dp[j-weight[i]] + value[i] > dp[j]) dp[j] = dp[j-weight[i]] + value[i]; } } cout << dp[w] << endl;}//二维数组void twoArray(int n, int w, int weight[], int value[]){ int dp[n+1][w+1] = {0}; memset(dp, 0, sizeof(dp)); //将dp二维数组的值设置成 0 for (int i = 1; i <= n; ++i) { for (int j = weight[i]; j <= w; ++j) { if (dp[i-1][j-weight[i]] + value[i] > dp[i-1][j]) dp[i][j] = dp[i-1][j-weight[i]] + value[i]; cout << "dp" << i << j << "=" <<dp[i][j]; } cout <<endl; } cout << dp[n][w] << endl;}
阅读全文
0 0
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划—0-1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划——0/1背包问题
- 0-1背包问题——动态规划
- 动态规划——0-1背包问题
- 0-1背包问题——动态规划法
- 动态规划法——求解0-1背包问题
- 动态规划法——求解0-1背包问题
- 动态规划——0-1背包问题
- 在jQuery和Ajax中无法使用${pageContext.request.contextPath}
- UVA 10267
- 手工搭建vc自动构建服务器
- HDU
- hdu 5269 ZYB loves Xor I(字典树)
- 0-1 背包问题——动态规划
- 判断1000年-2000年之间的闰年
- python 模块
- Java多线程--JUC集合--ConcurrentHashMap
- opencv中的标准霍夫线变换HoughLines()的-学习笔记
- Python多进程和多线程
- 每次新版本build时,让软件的版本号自增
- 返回n个随机生成的数组
- C++STL一般总结