背包问题(动态规划)
2016-08-26 17:02
225 查看
背包问题
01背包:有N件物品和一个重量为M的背包。(每种物品均只有一件)第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使价值总和最大。
完全背包:
有N种物品和一个重量为M的背包,每种物品都有无限件可用。第i种物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包重量,且价值总和最大。
多重背包:
有N种物品和一个重量为M的背包。第i种物品最多有n[i]件可用,每件重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包重量,且价值总和最大。
01背包问题
在选择物品的时候,对每种物品i只有两种选择,即装入背包或不装入背包。不能讲物品i装入多次,也不能只装入物品的一部分。因此,该问题被称为0-1背包问题。
问题分析:令V(i,j)表示在前i(1<=i<=n)个物品中能够装入容量为就j(1<=j<=C)的背包中的物品的最大价值,则可以得到如下的动态规划函数:
1. V(i,0)=V(0,j)=0
2. (1) V(i,j)=V(i-1,j) j<wi
(2)V(i,j)=max{V(i-1,j) ,V(i-1,j-wi)+vi) } j>wi
(1)式表明:如果第i个物品的重量大于背包的容量,则装人前i个物品得到的最大价值和装入前i-1个物品得到的最大价是相同的,即物品i不能装入背包;
(2)个式子表明:如果第i个物品的重量小于背包的容量,则会有一下两种情况:
(a)如果把第i个物品装入背包,则背包物品的价值等于第i-1个物品装入容量位j-wi 的背包中的价值加上第i个物品的价值vi;
(b)如果第i个物品没有装入背包,则背包中物品价值就等于把前i-1个物品装入容量为j的背包中所取得的价值。显然,取二者中价值最大的作为把前i个物品装入容量为j的背包中的最优解。
#include <iostream> using namespace std; int V[200][200]; //前 i个物品 装入 容量为j 的背包中获得的最大价值 int max(int a,int b) { if(a>=b) return a; else return b; } int KnapSack(int n,int w[],int v[],int x[],int C) //函数返回容量为 C的背包最多能装多少价值物品 { int i,j; for(i=0;i<=n;i++) V[i][0]=0; for(j=0;j<=C;j++) V[0][j]=0; for(i=0;i<=n-1;i++) for(j=0;j<=C;j++) if(j<w[i]) //如果第i个物品的重量大于背包的容量,则装人前i个物品得到的最大价值和装入前i-1个物品得到的最大价是相同的,即物品i不能装入背包; V[i][j]=V[i-1][j]; else//如果第i个物品的重量小于背包的容量,则 取两种情况的最大值为最优解 V[i][j]=max(V[i-1][j],V[i-1][j-w[i]]+v[i]); j=C; for(i=n-1;i>=0;i--) { if(V[i][j]>V[i-1][j]) //选中的物品标记为1 { x[i]=1; j=j-w[i]; } else x[i]=0; } cout<<"选中的物品是:"<<endl; for(i=0;i<n;i++) cout<<x[i]<<" "; cout<<endl; return V[n-1][C]; } int main() { int s;//获得的最大价值 int w[15];//物品的重量 int v[15];//物品的价值 int x[15];//物品的选取状态 int n,i; int C;//背包最大容量 n=5; printf("请输入背包的最大容量:\n"); cin>>C; printf("输入物品数:\n"); cin>>n; cout<<"请分别输入物品的重量:"<<endl; for(i=0;i<n;i++) cin>>w[i]; cout<<"请分别输入物品的价值:"<<endl; for(i=0;i<n;i++) cin>>v[i]; s=KnapSack(n,w,v,x,C); printf("最大物品价值为:\n"); cout<<s<<endl; return 0; }
呵呵,未完待续
相关文章推荐
- 动态规划 (Dynamic Programming) 之 背包问题合辑 (Knapsack, Subset Sum, Partition and change making problem )
- 01背包问题 动态规划解法
- 动态规划解0-1背包问题
- poj1014 Dividing 动态规划 多重背包问题
- 动态规划求解0/1背包问题
- 动态规划 (Dynamic Programming) 之 背包问题合辑 (Knapsack, Subset Sum, Partition and change making problem )
- 0-1背包问题与完全背包问题C++实现 动态规划
- 0-1背包问题--动态规划解法
- 动态规划背包问题自己的理解:
- 用动态规划求如下解0/1 背包问题 (第八题)
- 动态规划 ------0-1背包问题
- 0-1背包问题的两种解法(回溯法和动态规划)
- 动态规划(背包问题)
- [动态规划]背包问题(找零/子集和/编辑距离)
- POJ 3624 0-1背包问题 动态规划
- 0-1背包问题及其动态规划求解之二——王晓东的书本解法
- 0-1背包问题(动态规划) 解题报告
- 动态规划解决0-1背包问题
- 0-1背包问题入门小结 动态规划(DP)经典题目 POJ324 POJ1276
- hdoj 1248(背包问题)(动态规划)