题目描述


基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注
将一堆正整数分为2组,要求2组的和相差最小。
例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的。
Input
第1行:一个数N,N为正整数的数量。
第2 - N+1行,N个正整数。
(N <= 100, 所有正整数的和 <= 10000)
Output
输出这个最小差
Input示例
5
1
2
3
4
5
Output示例
1


解题思想


/*
经典的0-1背包问题变形,原题可以转换成为
每个数为一个物品,先求出总物品的体积sum,
求出c=sum/2;
然后往背包为c的体积里面装数
为什么这么想就是对的呢?
求2组和的差值,设总和为sum,左边和为a,右边和为b,所求为|b-a|
|b-a| = b-(sum-b)=2*b-sum = |result|
可以认为result = sum-2*b 则result/2 = sum/2 - b
又因为sum/2为定值,所以要想让result/2尽可能的小,则b
需要尽可能的接近sum/2 
*/

代码


import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        //init
        int sum = 0;
        int c = 0;
        int[] a = new int[n+1];
        //input
        for(int i=1; i<=n; ++i){
            a[i] = sc.nextInt();
            sum += a[i];
        }
        c = sum/2;
        int[] dp = new int[c+1];
        //process
        for(int i=1; i<=n; ++i)
           for(int j=c; j>=0; --j){
           //这里体积和价值一样
                  dp[j] = j>=a[i] ?  Math.max(dp[j], dp[j-a[i]]+a[i]) : dp[j];
           }
         System.out.println(sum-2*dp[c]);
    }
}