HW.称砝码

在这里插入图片描述

while True:
    try:
        n = int(input())
        weight = list(map(int, input().split()))
        number = list(map(int, input().split()))

        def getresult1(weight, number):
            #方法1, 将砝码展开成数组,每个砝码占一个位置,然后进行深搜索
            #时间复杂度为2^len(array), 超时
            array = []
            for i in range(len(weight)):
                array += [weight[i]] * number[i]
            appeared = {}
            global count
            count = 0

            def DFS(index, path):
                if path not in appeared:
                    global count
                    count += 1
                    appeared[path] = 1

                if index == len(array):
                    return
                DFS(index + 1, path + array[index])
                DFS(index + 1, path)
            DFS(0,0)
            return count

        def getresult2(weight, number):
            # 对方法1进行改进, 不用展开,每次去0~number[i]个重为weight[i]的砝码
            # 包含大量的重复计算,这样的递归形式没法做memo, 还是超时
            appeared = {}
            global count
            count = 0

            def DFS(index, path):
                if path not in appeared:
                    appeared[path] =1
                    global count
                    count += 1
                if index == len(weight):
                    return
                for c in range(number[index]+1):
                    DFS(index+1, path + c * weight[index])
            DFS(0, 0)
            return count

        def getresult3(weight, number):
            #使用动态规划
            #dp[i]表示用前i个砝码能组成的重量的个数,用set数据结构可以成功AC
            #该方法也可以写成带记忆的递归
            dp = [set() for _ in range(len(weight)+1)]
            dp[0] = set([0])
            for i in range(1,len(dp)):
                tmp = []
                for c in range(number[i-1]+1):
                    tmp.append(c*weight[i-1])
                tmp = set(tmp)
                for a in dp[i-1]:
                    for b in tmp:
                        dp[i].add(a+b)
            return len(dp[-1])
        result = getresult3(weight, number)
        print(result )

    except:
        break




猜你喜欢

转载自blog.csdn.net/dpengwang/article/details/92964011