问题描述:
典型的0/1背包问题,使用动态规划进行求解
解决方案:
动态规划通常意义上是使用上一步的结果对这一步进行判决,因此需要构建的是一个能够对物品i(1=<i<=n)选取与上一步进行关联。在这里使用这种数据结构的目的是为了进行最优子策略的关联。
对于dp背包的物品的选择是1,背包剩余容量满足的时候,但是其价值的大小小于不装入的情况,这里就不进行物品的装入,但是相反的情况下就会满足需求这里的该步骤的最优策略是这一个物品的价值加上上一个物品的价值得到的局部最优的结果。还有一种情况是背包的剩余的容量无法装入物品,则这一个物品的最优价值就等于上一步该容量下的价值,即没有物品装入背包中。
程序的编写是数据结构+算法。这里要想使用动态规划的算法的话,确定的数据结构是对于构建0/1背包关于最优价值和剩余容量的二维数组。
#include<stdio.h>
#include<malloc.h>
//问题描述:使用动态规划算法求解0/1背包问题,使每一步的决策和上一步进行关联
#define MAXN 20
#define MAXW 100
int n=5, W=10;
int v[MAXN]={0,6,3,5,4,6};
int w[MAXN]={0,2,2,6,5,4};
int dp[MAXN][MAXW];
int x[MAXN];
int maxv=0;
void knap(){
int i, j;
for(i=0; i<=n; i++){
dp[i][0]=0;
}
for(i=0; i<=W; i++){
dp[i][0]=0;
}
for(i=1; i<=n; i++){
for(j=1; j<=W; j++){
if(j<w[i])
dp[i][j]=dp[i-1][j];
else{
if(dp[i-1][j]>=(dp[i-1][j-w[i]]+v[i])){
dp[i][j]=dp[i-1][j];
}else{
dp[i][j]=dp[i-1][j-w[i]]+v[i];
}
}
}
}
}
void buildx(){
int i, weight=W;
for(i=n; i>=1; i--){
if(dp[i][weight]==dp[i-1][weight]){
x[i]=0;
}else{
x[i]=1;
maxv+=v[i];
weight=weight-w[i];
}
}
}
int main(){
int i;
knap();
buildx();
// printf("%d", x[0]);
for(i=1; i<=n; i++){
if(x[i]==1){
printf("选择了%d\n", i);
}
}
printf("物品的总价值:%d", maxv);
return 0;
}
knap()是构建dp数组的过程,buildx()是找到最优解的x数组的过程,这里的选择了该物品的话,则这一层的最优价值必不等于上个物品该剩余容量下的最优价值,从这里进行判断是否选择了该物品。