每日一题(19)——数组分割(动态规划)

一、问题:

      1. 有一个无序、元素个数为2n的正整数数组,要求:如何能把这个数组分割为两个子数组,子数组的元素个数不限,并使两个子数组之和最接近。

      2. 有一个无序、元素个数为2n的正整数数组,要求:如何能把这个数组分割为元素个数为n的两个数组,并使两个子数组之和最接近。

 

input:

2

2 3 3 6

output:

the count of num: 1  the max sum of the num: 6 //解法3

the differece between two sub array is 2 //解法1、2、3

the index of selected num: 6 //解法3

 

二、分析:

         动态规划解策略,这个问题其实完全就是0-1背包问题公正陪审团问题与问题2一致)这两个问题的变体都可以总结为数组求和问题(又可分为:数组项数一定与数组项数不定两种)

假设数组A[1..2N]所有元素的和是SUM。令S(k, i)表示前k个元素中任意i个元素的和的集合。显然:
                S(k, 1) = {A[i] | 1<= i <= k}
                S(k, k) = {A[1]+A[2]+…+A[k]}
                S(k, i) = S(k-1, i) U { A[k] + x | x属于S(k-1, i-1) }
          按照这个递推公式来计算,最后找出集合S(2N, N)中与SUM最接近的那个和,这便是答案。这个算法的时间复杂度是O(2^N).
          因为这个过程中只关注和不大于SUM/2的那个子数组的和。所以集合中重复的和以及大于SUM/2的和都是没有意义的。把这些没有意义的和剔除掉,剩下的有意义的和的个数最多就是SUM/2个。所以,我们不需要记录S(2N,N)中都有哪些和,只需要从SUM/2到1遍历一次,逐个询问这个值是不是在S(2N,N)中出现,第一个出现的值就是答案。我们的程序不需要按照上述递推公式计算每个集合,只需要为每个集合设一个标志数组,标记SUM/2到1这个区间中的哪些值可以被计算出来。

 

三、 数组求和问题分析:

       由于对两个子数组和最接近的判断不太直观,我们需要对题目进行适当转化。我们知道当一个子数组之和最接近原数组之和sum的一半时,两个子数组之和是最接近的。所以转化后的题目是:从2n个数中选出任意个数,其和尽量接近于给定值sum/2

       与

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值