简单01背包

I样

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

这是个什么问题呢?DP,贪心,数据结构,图论,数论还是计算几何?管他呢,反正胖巨巨都会,虽然胖巨巨走得早。
现在有n个数Xi,现在你要把这些数分成两组A,B,使得abs(sum(A)-sum(B))尽可能的小,并且每个Xi必须且只能分
到一组中,每组至少包含一个数字。
sum()表示计算累加和,abs()表示计算绝对值。

输入

 输入有多组。对于每组数据:
第一行输入一个n(1 <= n <= 100),接下来的n行每行一个整数Xi(1 <= Xi <= 50)。

输出

 对于每组数据,如果你能完成任务输出一个整数代表答案,否则输出-1。

示例输入

3
3
1
2
2
2
10

示例输出

0
8


解题心得: 题面来自SDUTOJ,前段时间面试时的笔试题原题生气,一个字都不带变的,抓狂 但额当时就是没想起来用背包,面试官

更是用二分给我讲了一遍,到现在我也没明白面试官当时是怎么个意思委屈,回来后给学弟们一说,各位ACM大神果断给出了答案:背包!

OJ原题! 然后就抛给了我上面这个题面, 我那个后悔啊! 如果当时能想起来用背包然后再弱弱的给面试官说:sorry,我还有个更

优的。。这该多diao啊你说说生气,哎 好了不做梦了,从现在开始努力吧!

上代码:

 
#include<iostream>
#include<string.h>
#include<cmath>
using namespace std;
int main()
{
    int n,i,j,a[11000],dp[10010],sum;
    while(cin>>n)
    {
        memset(dp,0,sizeof(dp));
        sum=0;
    for(i=0;i<n;i++)
    {
        cin>>a[i];
        sum+=a[i];
    }
    int tt=sum/2;
    for(i=0;i<n;i++)
    {
        for(j=tt;j>=0;j--)
        {
            if(j>=a[i])
            {
                dp[j]=max(dp[j],(dp[j-a[i]]+a[i]));
            }
        }
    }
    if(n==1)
    {
        cout<<"-1"<<endl;
    }
    else
    {
        sum=abs(sum-2*dp[tt]);
        cout<<sum<<endl;
    }
    }
    return 0;
}


你可能感兴趣的:(简单01背包)