NYOJ-456 邮票分你一半(典型的01背包问题)

看了两个多小时的01背包问题,这是做出来的第一道,Happy~!

提议可以这样来理解,要求邮票的分值之差最小,就是邮票分成两堆即两个容器,

而每张邮票只有选和不选两种状态,所以只要求出每个容器的最大装载量即可,

这样就转化为01背包问题了。这和zb的生日那道题一样只要代码稍作休改就能过。

score[j]代表的是容量为j的容器所能装载邮票的最大分值。得出递推关系式:

score[j] = score[j] > score[j-a[i]]+a[i] ? score[j] : score[j-a[i]]+a[i];

其中a[i]是第i个邮票的分值

View Code
 1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4
5 int score[10001],a[10001];
6 int main()
7 {
8 int i, j, sum, total;
9 int ncases, n;
10
11 scanf("%d",&ncases);
12 while( ncases-- )
13 {
14 total = 0;
15 memset(score,0,sizeof(score));
16 scanf("%d",&n);
17 for(i=1; i<=n; i++)
18 {
19 scanf("%d",&a[i]);
20 total += a[i];
21 }
22 sum = total/2;
23 for(i=1; i<=n; i++)
24 for(j=sum; j>=a[i]; j--)
25 {
26 score[j] = score[j] > score[j-a[i]]+a[i] ? score[j] : score[j-a[i]]+a[i]; //表示选择第i个邮票和不选择第i个邮票那个分支更大,选择更大的。
27 }
28 printf("%d\n",total-2*score[sum]);
29 }
30 //system("pause");
31 return 0;
32 }

你可能感兴趣的:(问题)