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.運行結果:

在這裏插入圖片描述

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