【问题】:输入为一个list,将其拆分,获得两个新的list:list1,list2,要求这两个list和的差值的绝对值最小:min:abs(sum(list1)-sum(list2))。
【解决】:
首先计算sum(list),求得sum / 2然后,利用0-1背包思路,填充一个最大容量为w = sum / 2的背包。则两个list的差值的绝对值为:min = sum(list)- 2 * result
动态规划递推式为:
R(n,w)= max(R(n-1, w), R(n-1,w-List(n))+ List(n))
-------------------------------------------------------------------------------------------------------------
一个类似的问题:
现有100名学生的成绩,每个班级50人,要求两个班级的平均分越接近越好,如何分配两个班级?
【解决】假设分成A和B两个班,每个学生的成绩都在 [0,100] 的区间内,每个学生成绩存在数组 a[100] 中。
状态:
用三维状态 来表示当前A班总分为i(0<=i<=5000)(如果A班总分超过分数总和一半被认为没有意义,所以上限为分数最大可能的总和10000的一半),人数为前j个(0<=j<=100),A班人数为k个(0<=k<=50)的时候,A班比B班高出多少分。
初始化:
,认为当只取前1个人时,该人在A班,A班当前总分为a[1],A班比B班的分高出a[1]分。
同理,,认为当只取前1个人时,该人在B班,A班当前总分为0,A班比B班的分高出-a[1]分。
显然,最终答案为
转移方程:
当我知道的时候,对于第j+1个学生的分数a[j+1],做如下处理:
- 把j+1这个学生放到A班中:
- 把j+1这个学生放到B班中:
复杂度就是状态数:(M是总分上限/2,N是人数),成功从阶乘的复杂度级别降级。
-------------------------------------------------------------------------------------------------------------