您的位置:首页 > 其它

动态规划求解0-1背包问题

2017-09-18 16:23 281 查看

动态规划求解0-1背包问题

问题描述:

给定N中物品和一个背包。物品i的重量是wi,其价值位vi ,背包的容量为C。问应该如何选择装入背包的物品,使得转入背包的物品的总价值为最大?

在选择物品的时候,对每种物品i只有两种选择,即装入背包或不装入背包。不能讲物品i装入多次,也不能只装入物品的一部分。因此,该问题被称为0-1背包问题。

问题分析:令V(i,j)表示在前i(1<=i<=n)个物品中能够装入容量为就j(1<=j<=C)的背包中的物品的最大价值,则可以得到如下的动态规划函数:

(1) V(i,0)=V(0,j)=0

(2) V(i,j)=V(i-1,j) j < wi

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>
#include<stdio.h>

using namespace std;
int V[15][100];
void GetMaxValue(int n, int k,int a[15],int b[15], int *s){
const int *w = a;
const int *v = b;

for(int i = 0; i <= k; i++){
V[0][i] = 0;
}
for(int i = 0; i <= n; i++){
V[i][0] = 0;
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= k; j++){
if(j < w[i-1])
V[i][j] = V[i-1][j];
else
V[i][j] = max(V[i-1][j], V[i-1][j-w[i-1]]+v[i-1]);
}
}
int y = k;
for(int i = n; i > 0; i--){
if(V[i][y] != V[i-1][y]){
s[i-1] = 1;
y = y - w[i-1];
}
}
}

int main(){
int w[15];
int v[15];
int s[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int n;
int k;

cout<<"请输入背包的最大容量:";
cin>>k;

cout<<"请输入物品总数:";
cin>>n;

cout<<"请输入每个物品的重量:"<<endl;
for(int i = 0; i < n; i++){
scanf("%d",w+i);
}
cout<<"请输入每个物品的价值:"<<endl;
for(int i = 0; i < n; i++){
scanf("%d",v+i);
}
GetMaxValue(n, k, w, v, s);
cout<<V
[k]<<endl;
for(int i =0; i< n; i++){
if(s[i])
cout<< i <<" ";
}
cout<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: