您的位置:首页 > 其它

动态规划三部曲之01背包问题的分析和实现(二)

2015-06-30 10:28 756 查看
用w[i]表示第i件物品的重量

用v[i]表示第i件物品的价值

用f[i][j]表示用能 装下总重量为j的背包去装前i件物品能够装最大的价值

思考动态规划的第一点----最优子结构:

对于前i件物品,以及给定的包容量,要么第i件物品装进去,要么不装进去,f[i][j]必然存在于二者之一。

思考动态规划的第二点----子问题重叠:

对于任意前k件物品,最大价值f[k]
都是同一类问题,即子问题重叠

思考动态规划的第三点----边界:

显然当包承重j为0时,f[i][j]=0,当物品件数为0时,f[i]j]=0这就是边界条件

思考动态规划的第四点----子问题独立:

第i件物品选择或者不选择是没有任何相互之间的影响的,即二者之间相互独立。

源码实现如下:

#include<iostream>
using namespace std;

int package01(int w[],int v[],int m,int n,int **&fm,int *&result)
	{
		int maxValue=0;
		int x,y;//记录去取得最大值时f的坐标
		int**f=(int **)malloc((m+1)*sizeof(int*));
		int *results=(int *)malloc((m+1)*sizeof(int));
		for(int i=0;i<(m+1);i++)
		{
			f[i]=(int *)malloc((n+1)*sizeof(int));
			
		}
		for(int i=0;i<=m;i++)
		{
			f[i][0]=0;
			results[i]=0;
		}
		for(int j=0;j<=n;j++)
		{
			f[0][j]=0;
		}
		for(int i=1;i<=m;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(j<w[i])
					f[i][j]=f[i-1][j];
				else
				{
					if((f[i-1][j-w[i]]+v[i])>f[i-1][j])
					{
						f[i][j]=f[i-1][j-w[i]]+v[i];
						
					}
						
					else
						f[i][j]=f[i-1][j];
				}
			}
		}
		fm=f;
		result=results;	
		for(int i=1;i<=m;i++)
		{
			for(int j=1;j<=n;j++)
			{
				
					
				cout<<f[i][j]<<" ";
			}
		cout<<endl;
		}

		while(y>=1&&f[x-1][y]!=f[x][y])//f[x-1][y]!=f[x][y]表示第x件物品放入了背包中
		{//该函数用于逆推出最大容量选择的物品

			result[x]=1;
			y=y-w[x];
			x=x-1;
		}
		return f[i][j];
	}

void main()
{
	cout<<"进来了"<<endl;
	int m;//物品数量
	int n;//背包容量 
	int maxValue;//存放背包能装的最大价值
	
	cout<<"请输入物品数量"<<endl;
	cin>>m;
	cout<<"请输入背包容量"<<endl;
	cin>>n;
	int *w=(int*)malloc(sizeof(int)*(m+1));//存放物品重量
	int *p=(int*)malloc(sizeof(int)*(m+1));//存放物品价值
	int *result;//存放最终选择的物品标记,如果物品被选中,则该位置置1
	int **f;//存放价值的二维数组
	 

	cout<<"请输入物品重量:"<<endl;
	for(int i=1;i<=m;i++)
	{
		cin>>w[i];
	}
	cout<<"你输入的物品重量为:"<<endl;
	for(int i=1;i<=m;i++)
	{
		cout<<w[i]<<" ";
	}
	cout<<endl;
	cout<<"请输入物品价格:"<<endl;
	for(int i=1;i<=m;i++)
	{
		cin>>p[i];
	}
	cout<<"你输入的物品价格:"<<endl;
	for(int i=1;i<=m;i++)
	{
		cout<<p[i]<<" ";
	}
	cout<<endl;
	maxValue=package01(w,p,m,n,f,result);
	cout<<"外面的输出结果"<<endl;
	for(int i=1;i<=m;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(maxValue<f[i][j])
					maxValue=f[i][j];
				cout<<f[i][j]<<" ";
			}
		cout<<endl;
		}
	cout<<"最大价值为:"<<maxValue<<endl;
	cout<<"标记结果"<<endl;
	for(int i=1;i<=m;i++)
		cout<<result[i]<<" ";
	cout<<endl;
	system("pause");
	
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: