现在有一个数字序列, a1 a2 a3......aN, 共N个正整数,其和为S。现在要从这个数字序列中取若干个数,使得这若干个数的和最接近S/2。比如现在有一个数字序列:1,2,3,4,5,6,7,8,9,10,10,9,8,7,6,5,4,3,2,1,1,2,3,4,5,6,7,8,9,11,其和为166,现在要在这个序列中取若干个数使得和最接近83,应该如何去取这个序列?
    我用了回溯加剪枝什么的,总算是算出来的。问题是,这是一道小学生信息学竞赛的编程题,排列组合那一讲的,有没简单点直白点的方法?

解决方案 »

  1.   

    分赃?  有分别重1,2,3,4,5,6,7,8,9,10,10,9,8,7,6,5,4,3,2,1,1,2,3,4,5,6,7,8,9,11的金条,要分成各83的两份。
    2-2凑对  就剩下1,2,3,4,5,6,7,8,9,11
    A:1,2,3,4,5,6,7,8,9,10,1,4,5,8 
    B:1,2,3,4,5,6,7,8,9,10,2,3,6,7
    剩下 11- 9 = 2  A拿11,B拿9多了2,A找还B2/2 = 1最终方案
    A:2,3,4,5,6,7,8,9,10,1,4,5,8,11 
    B:1,1,2,3,4,5,6,7,8,9,10,2,3,6,7,9
      

  2.   

    排序后p1 p2 p3 p4 p5 ......pn
    p1 p4 p5 p8 p9  p12......给A
    p2 p3 p6 p7 p10 p11.....给B
    然后算差值  多的一方(假设是A)A找还 差值的一半给另一方B (从小到大给,不小于为止,若超出,则B再找还)辗转相减 
    PS:有点辗转相除法的意味
      

  3.   

    或者省掉第一步  
    全部给A  然后A找还多的部分给B(从小到大给,不小于为止,若超出,则B再找还)
    这样辗转相减 就可以得到
    例这题
    1 A所有 B无
    2 A找还 B(1,1,1,2,。。7,7,7)= 84(A82 B84)
    3 B应找还A 1个 (1) = 1 刚好方案 A 1 8 8 8 9 9 9 10 10  11
    B 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 
      

  4.   

    按楼上的方法写了一个,测试用例太少,也不知道对不对。很感谢楼上的erqieshi```declare sub SelectSort(a() as integer, n as integer, ascend as integer)data 1,2,3,4,5,6,7,8,9,10,10,9,8,7,6,5,4,3,2,1,1,2,3,4,5,6,7,8,9,11
    dim as integer N =30, a(N), one, another, sum = 0
    dim as integer i, count = 0
    dim as integer MIN = 1000000, rec_diff, rec_first, rec_second, rec_count, rec_arr(N)
    for i = 1 to N
        read a(i)
        sum = sum + a(i)
    next i
    SelectSort(a(), N, 1)'升序排列one = sum
    another = 0
    do while abs(one-another) < MIN
        rec_diff = one-another
        rec_first = one
        rec_second = another
        rec_count = count
        rec_arr(rec_count) = a(rec_count)
        MIN = abs(one-another)
        one = one - a(count+1)
        another = another + a(count+1)
        count = count + 1
    loopif rec_second > rec_first then
        i = 1
        one = rec_first + rec_arr(i)
        another = rec_second - rec_arr(i)
        do while abs(one - another) < MIN
            MIN = abs(one - another) 
            rec_first = one
            rec_second = another
            i = i+1
            one = one + rec_arr(i)
            another = another - rec_arr(i)
        loop
    end if
    if rec_first >= rec_second then ? rec_first else ? rec_secondsleep
    end