一道典型的动态规划题目
因为题目要求使箱子的剩余空间最小的情况,相当于求箱子容量减箱子剩余空间最大的情况。
所以说状态转移方程为:
f[j]=max(f[j],f[j-w[i]]+w[i]);//求最大情况,不断更新
当我们推出动态转移方程之后,这道题就很简单了,所以请看代码:
1 #include<cstdio>
2 #include<iostream>
3
4 using namespace std;
5
6 int a[40], f[20005];
7
8 int main(){
9 int v, n;
10 scanf("%d%d",&v, &n);
11 for(int i = 1; i <= n; i++){
12 scanf("%d",&a[i]);
13 }
14 for(int i = 1; i <= n; i++){
15 for(int j = v; j >= a[i]; j--){
16 if(f[j] <= v)//如果这个箱子还没装满
17 f[j] = max(f[j], f[j-a[i]] + a[i]);//则将箱子容量减箱子剩余空间最大的情况进行更新
18 //将f[j]与 f[j-a[i]] + a[i]进行比较,f[j]即为没向里加之前的情况,f[j-a[i]] + a[i]即为向内加入后的情况
19 if(f[j] == v){//如果正好满了
20 printf("0");
21 return 0;
22 }
23 }
24 }
25 printf("%d",v - f[v]);//f[v]一直储存的是最大的所占空间,用v减去它,即可得最小的剩余空间
26 return 0;
27 }