有这样一个问题:有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。
要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
问题分析:令d[i]表示在前i(1<=n<=n)个物品中能够装入最大容量的背包中物品的最大体积。可以得到下面的动态规划函数:
(1)v[i] = v[i-1] = 0;
(2)v[i] = max{v[i-vi],v[i-vi]+vi};
(1)式表明:如果第i件物品的体积大于背包的体积,则装入前i个物品的体积和前i-1个物品的体积是相同的,即物品i不能放入背包
(2)式表明:如果第i间物品的体积小于背包的体积,可分为两种情况:
a:把第i件物品装入背包,则背包的体积等于前i-1件物品的体积v[i-vi](vi为第i件物品的体积)加上第i件物品的体积;
b:没有把第i件物品装入背包,则背包的体积就等于前i-1件物品装入的体积
上述两种情况选择最大值即为最优解
#include<stdio.h>
#define max(a,b) a>b?a:b;
int main() {
int v,i,j,n;
int a[20001];
int d[20001];
memset(d,0,sizeof(d));
scanf("%d %d",&v,&n);
for(i=0; i<n; i++){
scanf("%d",&a[i]);
}
for(i=0; i<n; i++){
for(j=v; j>=a[i]; j--){
d[j] = max(d[j],d[j-a[i]]+a[i]);
if(d[j]==v){
printf("0");
return 0;
}
}
}
printf("%d",v-d[v]);//背包最后剩余的体积
return 0;
}