c++动态规划——背包问题

问题基础:有N件物品和一个容量为C的背包。第i件物品的体积是W[i],价值是V[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。

c++动态规划——背包问题_第1张图片怎样才能得到放入书包物品的的最大价值呢?

解决方法——【动态规划】

运筹学的分支,纠结决策过程最优化的数学方法
把多阶段问题分解为相互联系单一阶段小问题求解,上一阶段的决策可以对下一阶段的决策产生影响
各个阶段的决策选择最优,从而使整个过程达到最优

令Vi、Wi 分别表示第i个物品的价值和体积,V(i,j)表示前i个物品能装入背包容量为j的背包的最大价值,有以下动态规划函数:

c++动态规划——背包问题_第2张图片

算法大概:即填写二维矩阵,行数为物品个数加1,列数为背包承重加1

例如,有5个物品,其重量分别是{2, 2, 6, 5, 4},价值分别为{6, 3, 5, 4, 6},背包的容量为10,求装入背包的物品和获得的最大价值。

第一阶段,只装入前1个物品,要求能够得到最大价值;
第二阶段,只装入前2个物品,要求能够得到最大价值;这个问题求解要在第一阶段最优解的基础上进行;
依此类推,直到第n个阶段。
最后,V(n,C)便是在容量为C的背包中装入n个物品时取得的最大价值。
每个阶段问题的求解都是基于前一个阶段的解是最优的基础上。

c++动态规划——背包问题_第3张图片

每次增加一个物品放入背包,如果可以放入,设该物品重量为w1,价值v1,得到其放入之后背包的总重量W,减去这个物品的重量w1,那么W-w1这个重量的列的最大价值加上v1如果大于该位置(该行该列)上一行的价值的值,就更新此处的value值,表明这个物品放入背包,不然就继承上一行的value值。

直接上代码:

#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include 
#include
#include 
using namespace std;  

void Add(int *m[],int weight[],int value[],int num,int content)//n代表物品的个数   
{    
	int i,j;
    for(j=0;j<=content;j++)//采用从底到顶的顺序来设置m[i][j]的值,首先放weight[num]
	{
       if(j=1;i--)//对剩下的num-1个物品进行放置  
	{  
        for(int j=0;j<=content;j++)
		{ 
			if(jm[i+1][j-weight[i]]+value[i]?m[i+1][j]:m[i+1][j-weight[i]]+value[i];    
			}
		}
	}
}  
void putout(int *m[],int num,int content,int x[],int weight[])  
{  
    int j=content,i;  
    for(i=1;i<=num-1;i++)
	{
        if(m[i][j] == m[i+1][j])
		{
			x[i]=0;//0表示不放进背包该物品
		}
        else                    
		{   
			x[i]=1;//放进背包该物品
			j=j-weight[i];  
		}      
	}
    x[num]=m[i][j]?1:0;   
}  
int main()  
{  
	while(true){
		int times=100000,t;//运行总次数
		double alltime=0;
		int num,content; //物品的个数和背包容量
		cout<<"输入物品个数:";
		cin>>num;
		cout<<"输入背包容量:";
		cin>>content;
		int *weight=new int[num+1];//物品的重量,其中0号位置不使用 。   
		int *value=new int[num+1];//物品对应的待加,0号位置置为空。 
		int i,j;
		for(t=0;t
代码中还包括运行时间的计算,随机数的生成。

你可能感兴趣的:(算法设计篇)