1.問題重述
給定n種物品和一揹包。物品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;
}