题目有点拗口,举个例子,有1,2,3一共3个数,将这三个数分成两部分,有3种分法1 | 2,3或者1,2| 3 或者1,3|2,然后计算每部分所有数的和,
1 | 2,3 -> 和为1,5,和的差是4
1 2| 3 -> 和为3,3,和的差是0
1 3|2 -> 和为4,2,和的差是2
所以按照1,2| 3分得到的和的差最小。
那么任意给定一个数组,如何找出最小值呢?
思路:差最小就是说两部分的和最接近,而且和所有数的和SUM的一半也是最接近的。假设用sum1表示第一部分的和,sum2表示第二部分的和,SUM表示所有数的和,那么sum1+sum2=SUM。假设sum1
所以我们就有目标了,使得sum1<=SUM/2的条件下尽可能的大。也就是说从n个数中选出某些数,使得这些数的和尽可能的接近或者等于所有数的和的一般。这其实就是简单的揹包问题了:
揹包容量是SUM/2. 每个物体的体积是数的大小,然后尽可能的装满揹包。
dp方程:f[i][V] = max(f[i-1][V-v[i]]+v[i], f[i-1][V] )
f[i][V]表示用前i个物体装容量为V的揹包能够装下的最大值,f[i-1][V-v[i]]+v[i]表示第i个物体装进揹包的情况,f[i-1][V]表示第i件物品不装进揹包的情况。
按照dp方程不难写出代码:
初始值:f[0][k]=0,f[i][0]=0;
for(i=0;i
{
for(j=1;j
{
f[i][j]=f[i-1][j];
if(v[i]<=j && f[i-1][j-v[i]]+v[i]>f[i][j]){
f[i][j]=value[i-1][j-v[i]]+v[i];
}
}
最终差值就是SUM-2*f[n-1][SUM/2];