0-1揹包問題 動態規劃法

iamzxf發表於2014-10-23

0-1揹包問題:給定n種物品和一個揹包,物品i的重量是wi,價值是vi,揹包的容量是c。應如何選擇裝入揹包的物品,使裝入揹包的物品的價值最大?

例項:n=5,c=10, v={6 3 5 4 6}, w={2 2 6 5 4},最優值是15.


//0-1揹包問題
#include <stdio.h>

#define min(a,b) a>b?b:a
#define max(a,b) a>b?a:b

int main()
{
	int n,c;
	int *w,	*v,*flag; //w代表每個物品的容積,v代表價值, flag代表是否出現
	int **m; //m[i,j]用來儲存當剩餘容量為j時,可選擇的物品為i,i+1,...時,0-1揹包問題的最優值
	int i,j,k;
	int jMax;	

	printf("please input the number of things and the volume of the knap:");
	scanf("%d %d",&n,&c);
	
	w=new int [n];
	v=new int [n];
	flag=new int [n];

	m=new int *[n];
	for(i=0;i<n;i++)
		m[i]=new int [c+1];

	printf("input the volume of each thing:");
	for(i=0;i<n;i++)
		scanf("%d", &w[i]);

	printf("input the value of each thing:");
	for(i=0;i<n;i++)
		scanf("%d",&v[i]);

	//從最後一個元素倒著推導,即第n-1個元素
	jMax=min(w[n-1]-1,c);
	for(j=0;j<=jMax;j++)
		m[n-1][j]=0;
	for(j=w[n-1];j<=c;j++)
		m[n-1][j]=v[n-1];

	for(i=n-2;i>0;i--)
	{
		jMax=min(w[i]-1,c);
		for(j=0;j<jMax;j++)
			m[i][j]=m[i+1][j];
		for(j=jMax;j<=c;j++)
			m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]);
	}

	m[0][c]=m[1][c];
	if(c>=w[0]) 
		m[0][c]=max(m[1][c],m[1][c-w[0]]+v[0]);	

	printf("the max value is %d. and the concrete are:\n",m[0][c]);

	for(i=0;i<n-1;i++)
	{
		if(m[i][c]==m[i+1][c]) 
			flag[i]=0;
		else
		{
			flag[i]=1;
			c=c-w[i];
		}
		flag[n-1]=(m[n-1][c])?1:0;
	}

	for(i=0;i<n;i++)
		if (flag[i])
			printf("%d ",v[i]);

	printf("\n");

	return 0;
}







相關文章