夜深人静写算法——01背包(动态规划)

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; 
}

猜你喜欢

转载自blog.csdn.net/curtern/article/details/84033594