0-1揹包问题【动态规划】

1.问题重述

给定n种物品和一揹包。物品i的重量是wiw_i,其价值为viv_i,揹包的容量为c。问应如何选择装入揹包中的物品,使得装入揹包中物品的总价值最大?

2.算法分析步骤:

动态规划法:
动态规划与分治法类似,都是把大问题拆分成小问题,通过寻找大问题与小问题的递推关系,解决一个个小问题,最终达到解决原问题的效果,01揹包问题满足最优性原理。
寻找递推关系式,面对当前物品有两种可能性:
包的容量比该物品体积小,装不下,此时的价值与前i-1个的价值是一样的,即V(i,j)=V(i-1,j);
还有足够的容量可以装该物品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个,即V(i,j)=max{V(i-1,j),V(i-1,j-w(i))+v(i)}
其中V(i-1,j)表示不装,V(i-1,j-w(i))+v(i) 表示装了第i个物品,揹包容量减少 w(i)但价值增加了v(i);
由此可以得出递推关系式:
在这里插入图片描述

3.代码描述:

#include<stdio.h>
int c[10][100];//对应每种情况的最大价值 
int knapsack(int m,int n)
{
	int i,j,w[10],v[10];
	printf("请输入每个物品的重量,价值:\n");
	for(i=1;i<=n;i++)
	    scanf("%d,%d",&w[i],&v[i]);
	for(i=0;i<10;i++)
	    for(j=0;j<100;j++)
	        c[i][j]=0;//初始化数组 
	for(i=1;i<=n;i++)
	    for(j=1;j<=m;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];
		}
		return (c[n][m]);
}
int main()
{
	int m,n;
	int i,j;
	printf("请输入揹包的容量,物品总个数:\n");
	scanf("%d,%d",&m,&n);
	printf("揹包能装的最大总价值为%d",knapsack(m,n));
	printf("\n");
	return 0;
}

4.运行结果:

在这里插入图片描述

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