01背包:
一:
01背包问题需要求解的就是,体积V的背包中物体总价值最大化,第N件物品中第i件是否要放入背包中?(其中每个物品最多只能放一件) ( 物品体积为w[i],物品价值为v[ i ] ) ;
二:
定义二维数组 dp[ i ][ j ]表示当前背包大小为 j 时,对于第 i 件物品的最优解(可能放入,也可能不放入);
动态规划方程:
(1) j < w[ i ] : dp[ i][ j ] = dp[ i + 1][ j ] (背包体积不够, 物品不放入,跳到下一个物品的最优解);
(2) j >= w[i] : dp[ i ][ j ] = max(dp[ i + 1][j - w[ i ]] + v[i], dp[i + 1][ j ]); (如果把物品放入背包,背包体积变成 j - w[i] )
三:
#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#define MAX 6
#define C 10
using namespace std;
int V = 0;
void backpack(int *v,int *w,int dp[MAX][C],int c,int n){
memset(dp,0,sizeof dp);
for(int i = n;i >=1 ;i--){
for(int j = 0;j <= c;j++){
if(j < w[i]&& i < n) //背包体积小于w[i],第i件物品不放入背包
dp[i][j] = dp[i+1][j];
else if(j < w[i] &&i==n)
dp[i][j] = 0;
else if(j >= w[i]&&i < n)
dp[i][j] = max(dp[i+1][j-w[i]]+v[i],dp[i+1][j]) ;
else if(j >= w[i] &&i == n)
dp[i][j] = v[i];
}
}
for(int i = 1; i <= MAX-1;i++){
for(int j = 0; j <= C;j++)
printf("%5d",dp[i][j]);
cout<<endl;
}
cout<<endl;
}
void Traceback(int *v,int *w,int dp[MAX][C],int n,int c){
bool judge = true;
if(dp[n][c] != dp[n+1][c]){
cout<<"将第"<<n<<"件物品放入背包"<<endl;
V+=v[n];
if(n<= MAX-2)
Traceback(v,w,dp,n+1,c-w[n]);
}
else
if(n <= MAX-2)
Traceback(v,w,dp,n+1,c);
}
int main(){
int weight[MAX]= {0,2,2,6,5,4};
int value[MAX] = {0,6,3,5,4,6};
int dp[MAX][C];
backpack(value,weight,dp,C,MAX-1);
Traceback(value,weight,dp,0,C);
cout<<endl<<"背包最大价值为"<<V<<endl;
return 0;
}