题意:给定n个数,要求从这n个数中的选取一些数和sum大于指定数b,要求sum-b最小。
解法:刚开始可以把所有n个数全部相加得到sum,sum肯定大于b,令m=sum-b,要尽量在这m中多的减去原来在sum中的数,使得m最小;
即从这n个数种选取几个数,使得在其和不超过m的情况下最大,这不就是一个01背包问题么。解之。
#include <stdio.h>
#include <string.h>
#define N 1000005
#define MAX(a, b)(a > b ? a : b)
int v[N], h[25];
int main()
{
int n, b, sum = 0;
scanf("%d %d", &n, &b);
for(int i = 0; i < n; i++)
{
scanf("%d", &h[i]);
sum += h[i];
}
b = sum - b;
for(int i = 0; i < n; i++)
for(int j = b; j >= h[i]; j--)
{
v[j] = MAX(v[j], v[j - h[i]] + h[i]);
}
printf("%d\n", b - v[b]);
return 0;
}