怎样用python实现将一组数尽可能均匀地分成两堆,使两个堆中的数的和尽可能相等?

麦克叔叔去世了,他在遗嘱中给他的两个孙子阿贝和鲍勃留下了一堆珍贵的口袋妖怪卡片。遗嘱中唯一的方向是“尽可能均匀地分配纸牌的价值”。作为Mike遗嘱的执行人,你已经为每一张口袋妖怪卡片定价,以获得准确的货币价值。你要决定如何将口袋妖怪卡片分成两堆,以尽量减少每一堆卡片的价值总和的差异。
例如,你有下列n=8 个口袋妖怪卡片:
图片说明

经过大量的工作,你发现你可以用下面的方法来划分卡片:
图片说明

这给了安倍10美元的牌给了鲍勃11美元的牌。这是最好的除法吗?
你要做的是解决n张牌的问题其中每张牌ci都有一个正整数值vi.你的解决方法是计算牌应该如何被分割以及每摞牌的价值。
输入输出示例如下:
图片说明

1.通过检查所有可能的桩以蛮力解决此问题。 对这种蛮力算法的时间复杂度进行分析,并通过实施和实验验证您的分析结果(既写出来算法的设计思路等),并用python算法实现编程

2.通过动态编程开发更有效的算法。 您应该首先通过动态编程的思想来分析此问题,并编写相应的递归属性。 对这种算法的时间复杂度进行分析,并通过实施和实验验证您的分析结果。并用python代码实现动态编程

def deal(data,flag):
    a=[]
    for i in data:
        if i>=flag:
            return [i]
        elif a==[]:
            a.append([i])
        else:
            a=a+[k+[i] for k in a if sum(k)+i<=flag]
            a.append([i])
    #return sorted(a,key=sum)[-1]
    target=sum(max(a,key=sum))
    return list(filter(lambda x:sum(x)==target,a))
if __name__=='__main__':
    c=[2,1,3,1,5,2,3,4]
    flag=sum(c)//2
    res=deal(c,flag)
    print(res)

算法复杂度最差是N的3次方

https://my.oschina.net/u/3764483/blog/1820160 可以看一下这篇博客

使用回溯法求解

#!/bin/python
# coding: UTF-8
# author    : wenhui, 2012-6-19 9:03:03
# dscrp     :
#                   若对于整数N,在集合{1,2……,N}中找出m个数,
#                   使其和等于剩下的N-m个数的和。返回所有可能的组合数。
#                   N<10000。

def _get_half_sum(total_sum, lst, lst_sum, unused_lst, ununsed_indx) :
    i = ununsed_indx
    if i < len(unused_lst) :
        # when contains unused_list[i]
        if lst_sum + unused_lst[i] == total_sum:
            lst.append(unused_lst[i])
            lst.sort()
            print("list:", lst, "\ttotal:", sum(lst))
            lst.remove(unused_lst[i])
#           break
        elif lst_sum + unused_lst[i] < total_sum :
            elem = unused_lst[i]
            # not contains unused_lst[i]
            _get_half_sum(total_sum, lst, lst_sum, unused_lst, i+1)
            # contains unused_lst[i]
            lst.append(elem)
            lst.sort()
            _get_half_sum(total_sum, lst, lst_sum + elem, unused_lst, i+1)

            # recover the lst & unused_lst
            lst.remove(elem)
    # if i < len(unused_lst)
# _get_half_sum 

def get_half_sum (N) :
    unused_lst = [i for i in range(1, N + 1)]
    lst = []
    if N * (N + 1) % 4 == 0 and N > 2:
        _get_half_sum(N * (N + 1) / 4, lst, 0, unused_lst, 0)
# get_half_sum

get_half_sum(int(input("please input N: ")))

你可以先排序然后依次取值
图片说明