動態規劃三部曲之01揹包問題的分析和實現(二)

用w[i]表示第i件物品的重量

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

用f[i][j]表示用能 裝下總重量爲j的揹包去裝前i件物品能夠裝最大的價值



思考動態規劃的第一點----最優子結構:

       對於前i件物品,以及給定的包容量,要麼第i件物品裝進去,要麼不裝進去,f[i][j]必然存在於二者之一。
思考動態規劃的第二點----子問題重疊:
       對於任意前k件物品,最大價值f[k][n]都是同一類問題,即子問題重疊
思考動態規劃的第三點----邊界:
       顯然當包承重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");
	
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章