动态规划--01背包问题(python)

一年多的学习,我不适合走算法这条路
但是基础性的知识还是要啃的,用于回忆

我将动态规划称之为 备忘录算法 (你不记录之前的数据就会很难受)

#!usr/bin/env python
# _*_ coding:utf-8 _*-
"""
@author: “ying chen”
@file: .py
@time: 2020/06/10
"""
# import os
# import sys
# import math

"""
五个商品,属性为 {价格 体积}, 体积限额为13, 求最大组合价值
饼干:9    4
啤酒:24   10
汽水:2    3
牛奶:9    4   
面包:10   5
"""
store = ([0, 0], [9, 4], [24, 10], [2, 3], [9, 4], [10, 5])  # 商品属性数组
Memo = [[None for _ in range(14)] for _ in range(6)]  # 构建备忘录数组
Memo_B = [[0 for _ in range(14)] for _ in range(6)]
Record = [[0 for _ in range(14)] for _ in range(6)]   # 商品选择记录(0:未选择, 1:选择)


# 1 暴力枚举法:递归求解

def fuck(i, v):
    if v < 0:
        return -10000
    elif i <= 0:
        return 0

    P1 = fuck(i - 1, v - store[i][-1])  # 选择了这个商品
    P2 = fuck(i - 1, v)  # 没有选择这个商品


    return max((P1 + store[i][0]), P2)

# 2 动态规划A :带备忘录的递归  自顶向下--自底向上

def DPA_fuck(i, v):
    if v < 0:
        return -10000
    elif i <= 0:
        return 0

    if Memo[i][v] is None:
        P1 = DPA_fuck(i - 1, v - store[i][-1])  # 选择了这个商品
        P2 = DPA_fuck(i - 1, v)  # 没有选择这个商品
        Memo[i][v] = max((P1 + store[i][0]), P2)

    return Memo[i][v]

# 3 动态规划B :递推求解  自底向上

def DPB_fuck(i, v,):
    for line in range(1, i+1):
        pi = store[line][0]
        vi = store[line][1]
        for column in range(1, v+1):
            if column >= vi and (pi + Memo_B[line-1][column-vi]) > Memo_B[line-1][column]:  # 1首先本列容量大于当前商品体积,
                                                                                            # 2本商品价格与减去本商品体积后的背包最优解之和 大于 本商品之前的最优解
                Memo_B[line][column] = pi + Memo_B[line-1][column-vi]   # 更新备忘录
                Record[line][column] = 1                                # 记录此商品被选中
            else:
                Memo_B[line][column] = Memo_B[line-1][column]           # 此商品不选,继承之前的最优解

    C = v
    for k in range(5, 0, -1):
        if Record[k][C]:
            print("选择第{}个商品".format(k))
            C = C - store[k][1]

    return Memo_B[i][v]



if __name__ == '__main__':
    print("现在开始\n")
    # print(fuck(5, 13))

    # print(DPA_fuck(5, 13))
    # for i in range(len(Memo)):
    #     print(Memo[i])
    print(DPB_fuck(5, 13))
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值