3 3 1 2 2 2 10
0 8
例如前辈给我出的数据:
5
10 8 9 5 4 正确结果应该是0,贪心的结果就挂了!
正确的算法是:如果想让两个分立的数字集合的abs()之差最小,也就是说让两个集合的各自的和尽可能的接近
(sum(集合a)+sum(集合b))/2. 即使不会完全均分也不要在意,因为我们要用接下来的背包来做,这个背包
不一定是装满的!
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <algorithm>
using namespace std;
int f[2600];
int main()
{
    int n;
    int p[150];
    int i, j;
    while(scanf("%d", &n)!=EOF)
    {
        int sum=0;
        for(i=0; i<n; i++)
            scanf("%d", &p[i] ), sum+=p[i];
        if(n==1)
        {
            printf("-1\n");
            continue;
        }
        memset(f, 0, sizeof(f));
        int dd=sum;
        sum=sum/2;
        //背包不一定要装满
        for(i=0; i<n; i++)
        {
            for(j=sum; j>=p[i]; j--)
                f[j] = max(f[j], f[j-p[i]]+p[i] );
        }
        dd=dd-f[sum];
        printf("%d\n", abs(f[sum]-dd) );
    }
    return 0;
}
原文:http://www.cnblogs.com/yspworld/p/4345625.html