ruijiege

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

哔哩哔哩:

6.二次优化(3)_哔哩哔哩_bilibili

第一个版本对动态规划的理解

# 问题有大量的重复问题,比如求feibolaqie(5) = feibolaqie(4)+feibolaqie(3),
# 所以有重复问题,通过缓存优化,把以前求过的问题做缓存
# def feibolaqie(n):
#     if n ==1:
#         return 1
#     elif n==2:
#         return 1
#     else:
#         return feibolaqie(n-1)+feibolaqie(n-2)
# print(feibolaqie(7))
# 题目有个机器人,在步长为n的数组中,从开始start位置,走K步到aim位置
# def ways(n, start, aim, k):
#     return process(start, aim, k, n)
#
#
# def process(cur, aim, rest, n):
#     if rest == 0:
#         return 1 if cur == aim else 0
#     if cur == 1:
#         return process(2, aim, rest - 1, n)
#     elif cur == n:
#         return process(n - 1, aim, rest - 1, n)
#     else:
#         return process(cur - 1, aim, rest - 1, n) + process(cur + 1, aim, rest - 1, n)
# 使用缓存对递归经行问题优化,傻缓存法
# def ways1(n, start, aim, k):
#     # 定义一个[n+1][k+1]的二维数组初始话为-1表示数据没有被复制,这里要用N因为可以走回去
#     dp = [[-1 for i in range(k+1)] for j in range(n+1)]
#     return process1(start, aim, k, n, dp)
#
#
# def process1(cur, aim, rest, n, dp):
#     if dp[cur][rest] != -1:
#         return dp[cur][rest]
#     ans = 0
#     if rest == 0:
#         ans = 1 if cur == aim else 0
#     elif cur == 1:
#         ans = process1(2, aim, rest - 1, n, dp)
#     elif cur == n:
#         ans = process1(n - 1, aim, rest - 1, n, dp)
#     else:
#         ans = process1(cur - 1, aim, rest - 1, n, dp) + process1(cur + 1, aim, rest - 1, n, dp)
#     dp[cur][rest] = ans
#     return ans
# 动态规划解决问题
def ways2(n, start, aim, k):
    # 定义一个[n+1][k+1]的二维数组初始话为-1表示数据没有被复制,这里要用N因为可以走回去,全部定义为0因为rest为0的时候只有目标值为1
    dp = [[0 for i in range(k + 1)] for j in range(n + 1)]
    # 只需要填充退出条件为rest = 0,因为rest为0的时候只有目标值为1
    dp[aim][0] = 1
    # 填充dp
    for rest in range(1, k + 1):
        dp[1][rest] = dp[2][rest - 1]
        for cur in range(2, n):
            dp[cur][rest] = dp[cur - 1][rest - 1] + dp[cur + 1][rest - 1]
        dp[n][rest] = dp[n - 1][rest - 1]
    return dp[start][k]


print(ways2(5, 2, 4, 6))
View Code

 题目给定一个整数arr,代表不同的数字>0,玩家A和玩家B依次拿走数组的最左或最右,AB都决定聪明,返回获胜者分数

# 题目给定一个整数arr,代表不同的数字>0,玩家A和玩家B依次拿走数组的最左或最右,AB都决定聪明,返回获胜者分数
def win1(arr):
    return max(f(arr, 0, len(arr) - 1), g(arr, 0, len(arr) - 1))


# 先手函数,我要选择当前值和后手值相加最大的
def f(arr, l, r):
    if l == r:
        return arr[l]
    p1 = arr[l] + g(arr, l + 1, r)
    p2 = arr[r] + g(arr, l, r - 1)
    return max(p1, p2)


# 后手函数,只能让先手选择最小的值,因为我们没得选
def g(arr, l, r):
    if l == r:
        return 0
    p1 = f(arr, l + 1, r)
    p2 = f(arr, l, r - 1)
    return min(p1, p2)

# 缓存法
def win2(arr):
    n = len(arr)
    fcash = [[-1 for _ in range(n)] for _ in range(n)]
    gcash = [[-1 for _ in range(n)] for _ in range(n)]
    return max(f2(arr, 0, n - 1, fcash, gcash), g2(arr, 0, n - 1, fcash, gcash))


# 先手函数,我要选择当前值和后手值相加最大的
def f2(arr, l, r, fcash, gcash):
    if fcash[l][r] != -1:
        return fcash[l][r]

    if l == r:
        ans = arr[l]
    else:
        p1 = arr[l] + g2(arr, l + 1, r, fcash, gcash)
        p2 = arr[r] + g2(arr, l, r - 1, fcash, gcash)
        ans = max(p1, p2)
    fcash[l][r] = ans
    return ans


# 后手函数,只能让先手选择最小的值,因为我们没得选
def g2(arr, l, r, fcash, gcash):
    if gcash[l][r] != -1:
        return gcash[l][r]
    if l == r:
        ans = 0
    else:
        p1 = f2(arr, l + 1, r, fcash, gcash)
        p2 = f2(arr, l, r - 1, fcash, gcash)
        ans = min(p1, p2)
    gcash[l][r] = ans
    return ans
# 动态规划
def win3(arr):
    n = len(arr)
    fcash = [[-1 for _ in range(n)] for _ in range(n)]
    gcash = [[0 for _ in range(n)] for _ in range(n)]
    for l in range(n):
        fcash[l][l] = arr[l]
    for cow in range(1, n):
        l = 0
        r = cow
        while r < n:
            fcash[l][r] = max(arr[l] + gcash[l + 1][r], arr[r] + gcash[l][r - 1])
            gcash[l][r] = min(fcash[l + 1][r], fcash[l][r - 1])
            l += 1
            r += 1

    return max(fcash[0][n - 1], gcash[0][n - 1])


print(win1([5, 7, 4, 5, 8, 1, 6, 0, 3, 4, 6, 1, 7]))
print(win2([5, 7, 4, 5, 8, 1, 6, 0, 3, 4, 6, 1, 7]))
print(win3([5, 7, 4, 5, 8, 1, 6, 0, 3, 4, 6, 1, 7]))
View Code

 

posted on 2023-05-21 16:34  哦哟这个怎么搞  阅读(37)  评论(0编辑  收藏  举报