UVA 562 Dividing coins

题目描述:给出一些不同面值的硬币,每个硬币只有一个。将这些硬币分成两堆,并且两堆硬币的面值和尽可能接近。

分析:将所有能够取到的面值数标记出来,然后选择最接近sum/2的两个面值

            状态表示:d[j]表示用当前给定的硬币是否可以凑得总面值j

            转移方程:d[j]=d[ j-coin[i] ]

                          开始时只取出硬币coin[0],判断它是否能凑得总面值j

                          每新加入一个硬币coin[i]时,判断所有已经取出的硬币能否凑得总面值j

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string.h>
 4 #include <cmath>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 bool dp[50001];
 9 int coin[101];
10 int n,sum;
11 int main()
12 {
13     int t,i,j;
14     scanf("%d",&t);
15     while( t--)
16     {
17         scanf("%d",&n);
18         sum =0;
19         for( i=0; i<n; i++)
20         {
21             scanf("%d",&coin[i]);
22             sum+= coin[i];
23         }
24         memset( dp,0, sizeof( dp));
25         dp[0]=1;
26         for( i=0; i<n; i++)
27             for( j=sum;j>=coin[i]; j--)
28                 if( !dp[j]) dp[j] =dp[j-coin[i]];
29         for( i=sum/2; i>=0;i--)
30             if( dp[i])
31             {
32                 printf("%d
",sum-i-i);
33                 break;
34             }
35     }
36     return 0;
37 }
原文地址:https://www.cnblogs.com/sage-blog/p/3646956.html