/*题目链接*/
题意:有一个箱子容量为V(正整数,0≤V≤20000),同时有n个物品(0<n≤30),每个物品有一个体积(正整数)。要求从n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
题目分析:最基本的01背包,用f[i][j]表示状态:把前i个物品装到容量为j的包中所能得到的最大价值。第i个物品的体积为c[i],相应的代价为w[i],(w[i] = c[i])。分析:将“前i个物品装进容量为j的包中所得到的最大价值”这个子问题的求解,考虑第i个物品,则会有两种策略:1、不选第i个物品,此时子问题的解为将“前i-1个物品装进容量为j的包中所得到的最大价值”即:f[i][j]=f[i-1][j];2、选择第i个物品,则子问题的解为将“第前i-1个物品装入背包容量为j-c[i]的包中所得到的最大价值”与第i个物品的价值之和, 即:f[i][j]=f[i-1][j-c[i]]+w[i]。
这样最后的状态转移方程就是
f[i][j] = max{ f[i-1][j], f[i-1][j-c[i]]+w[i] }
AC代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int n,m,i,j,v[50],f[20010]={0};
while (~scanf("%d",&m))
{
memset(f,0,sizeof(f));
scanf("%d",&n);
for (i=0; i<n; i++)
scanf("%d",&v[i]);
for (i=0; i<n; i++)
for (j=m; j>=v[i]; j--)
f[j] = f[j]>f[j-v[i]]+v[i]? f[j]:f[j-v[i]]+v[i];
printf("%d\n",m-f[m]);
}
return 0;
}