1. 程式人生 > >01揹包,完全揹包,多重揹包

01揹包,完全揹包,多重揹包

01揹包

#include <stdio.h>
int c[101][1001]={0};//定義100個物品1000重量的總價值陣列
void calcMaxValues(int n,int t_w)
{
	int i,j;
	int w[101]={0},v[101]={0};//w單個物品的重量,v單個物品的價值
	for(i=1;i<=n;i++){
		scanf("%d%d",&w[i],&v[i]);
	}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=t_w;j++){
			if(w[i]<=j){
				if(v[i]+c[i-1][j-w[i]]>c[i-1][j]){
					c[i][j]=v[i]+c[i-1][j-w[i]];
				}
				else{
					c[i][j]=c[i-1][j];
				}
			}
			else{
				c[i][j]=c[i-1][j];
			}
		}
	}
	printf("%d",c[n][t_w]);
}
int _tmain(int argc, _TCHAR* argv[])
{
	int num,weight;/*num表示物品的件數,weight表示能裝下物品的總重量*/
	scanf("%d%d",&num,&weight);
	calcMaxValues(num,weight);
	getchar();
	return 0;
}

01揹包的空間優化版
#include <stdio.h>
int c[1001]={0};//空間優化
void calcMaxValueAboutBagpack_optimize(int n,int t_w)
{
	int i,j;
	int w[101]={0},v[101]={0}; //w單個物品的重量,v單個物品的價值
	for(i=1;i<=n;i++){
		scanf("%d%d",&w[i],&v[i]);
	}
	for(i=1;i<=n;i++)//n件物品
	{
		for(j=t_w;j>0;j--){//物品的重量,或者說是容量  用逆序儲存
			if(w[i]<=j &&(v[i]+c[j-w[i]])>c[j]){ //如果重量可以放得下,且放下的值之和大於當前要放下位置的值
					c[j]=v[i]+c[j-w[i]];
			}
		}
	}
	printf("%d",c[t_w]);
}

int main()
{
	int num,weight;/*num表示物品的件數,weight表示能裝下物品的總重量*/
	scanf("%d%d",&num,&weight);
	calcMaxValueAboutBagpack_optimize(num,weight);
	getchar();
	return 0;
}

完全揹包

都是空間優化過的,這個還可以進行優化。如果物品A的價值小於物品B的價值,且物品A的容量大於物品B,那麼物品A不用考慮。

#include <stdio.h>
int c[1001]={0};//空間優化
void FullBagpack(int n,int t_w)
{
	int i,j;
	int w[101]={0},v[101]={0}; //w單個物品的重量,v單個物品的價值
	for(i=1;i<=n;i++){
		scanf("%d%d",&w[i],&v[i]);
	}
	for(i=1;i<=n;i++)//n件物品
	{
		for(j=1;j<=t_w;j++){//物品的重量,或者說是容量  用逆序儲存
			if(w[i]<=j &&(v[i]+c[j-w[i]])>c[j]){ //如果重量可以放得下,

且放下的值之和大於當前要放下位置的值
				c[j]=v[i]+c[j-w[i]];
			}
		}
	}
	printf("%d",c[t_w]);
}

int _tmain(int argc, _TCHAR* argv[])
{
	int num,weight;/*num表示物品的件數,weight表示能裝下物品的總重量*/
	scanf("%d%d",&num,&weight);
	FullBagpack(num,weight);
	getchar();
	return 0;
}

多層揹包

空間優化過

#include <stdio.h>


int c[1001]={0};//空間優化
void calcMaxValueAboutMultipleBagpack_optimize(int t_n,int t_w)
{
	int i,j;
	int w[101]={0},v[101]={0},n[101]={0}; //w單個物品的重量,v單個物品的價值,n表示每個物品的件數
	for(i=1;i<=t_n;i++){
		scanf("%d%d%d",&w[i],&v[i],&n[i]);
	}
	for(i=1;i<=t_n;i++)//n件物品
	{
		for(j=t_w;j>0;j--){//物品的重量,或者說是容量  同樣用01揹包逆序儲存解決空間量的問題
			if(w[i]<=j){ //如果重量可以放得下
				int cur_max_w=j/w[i];//cur_max_w表示能放下當前最大物品重量的幾倍
				if(cur_max_w>=n[i]){//如果當前能放下的個數小於或等於該物品設定的個數
					if (v[i]*n[i]+c[j-w[i]*n[i]]>c[j]) //且當前物品的價值*該物品的數量+沒放入該物品*數量時的價值 是否大於當前總價值
					{
						c[j]=v[i]*n[i]+c[j-w[i]*n[i]];
					} 	
				}
				else{
					if (v[i]*cur_max_w+c[j-w[i]*cur_max_w]>c[j]) //且當前物品的價值*該物品的數量+沒放入該物品*數量時的價值 是否大於當前總價值
					{
						c[j]=v[i]*cur_max_w+c[j-w[i]*cur_max_w];
					} 
				}
				
			}
		}
		//打印表格看看是否與預期的一樣
		for(int k=1;k<=t_w;k++)
		{
			printf("%d  ",c[k]);
		}
		printf("\n");
	}
	printf("%d",c[t_w]);
}

int main()
{
	int num,weight;/*num表示物品的件數,weight表示能裝下物品的總重量*/
	scanf("%d%d",&num,&weight);
	calcMaxValueAboutMultipleBagpack_optimize(num,weight);
	getchar();
	return 0;
}

說明:_tmian 是vs2010開發環境生成的,換成mian即可。