动态规划

题一:给定数组arr,求出arr中不相邻节点之和最大值

输入:arr = [1,2,4,1,7,8,3]
输出:15

解题思路:
o p t ( 0 ) = a r r [ 0 ] opt(0) = arr[0] opt(0)=arr[0]
o p t ( 1 ) = m a x { a r r [ 0 ] a r r [ 1 ] opt(1)=max \begin{cases} arr[0]\\ arr[1] \end{cases} opt(1)=max{arr[0]arr[1]

o p t ( i ) = m a x { 选 : o p t ( i − 2 ) + a r r [ i ] 不 选 o p t ( i − 1 ) opt(i)=max \begin{cases} 选:opt(i-2) + arr[i]\\ 不选opt(i-1) \end{cases} opt(i)=max{opt(i2)+arr[i]opt(i1)

#动态规划,本题求出arr中不相邻节点之和最大值
#解题思路:
arr = [1,2,4,1,7,8,3]
#方法一:递归
def rec_opt(arr,i):
    if i == 0:
        return arr[0]
    elif i == 1:
        return max(arr[0],arr[1])
    else:
        A = rec_opt(arr,i-2) + arr[i]
        B = rec_opt(arr,i-1)
        return max(A,B)
print(rec_opt(arr,6))

#方法二:非递归方法
import numpy as np
def dp_opt(arr):
    opt = np.zeros(len(arr))
    #下标0最优解就是arr[0]
    #下标1最优解是max(arr[0], arr[1])
    opt[0] = arr[0]
    opt[1] = max(arr[0], arr[1])
    for i in range(2,len(arr)):
        A = opt[i-2] + arr[i]
        B = opt[i-1]
        opt[i] = max(A, B)
    return opt[len(arr)-1]
print(dp_opt([4,1,1,9,1]))

题二:判断一个数,能否由列表中的数组成
递归出口
if s == 0: return True #space为0的时候,不放也满了
if i == 0: return arr[0] == s #当只剩一个数,只需判断与剩余空间s的大小
if arr[i] > s:
return subset(arr,i-1,s)

o p t ( i ) = m a x { 选 : s u b s e t ( a r r , i − 1 , s − a r r [ i ] ) 不 选 : s u b s e t ( a r r , i − 1 , s ) opt(i)=max \begin{cases} 选:subset(arr, i-1, s-arr[i]) \\ 不选:subset(arr, i-1, s) \end{cases} opt(i)=max{subset(arr,i1,sarr[i])subset(arr,i1,s)
方法一:递归

#递归出口
# if s == 0: return True
# if i == 0: return arr[0] == s
# if arr[i] > s:
#    return subset(arr,i-1,s)
arr = [3, 34, 4, 12, 5, 2]
def rec_subset(arr, i, s):
    if s == 0:
        return True
    elif i == 0:
        return arr[0] == s
    elif arr[i] > s:
        return rec_subset(arr,i-1,s)
    else:
        #选
        A = rec_subset(arr, i-1, s-arr[i])
        #不选
        B = rec_subset(arr, i - 1, s)
        return A or B
print(rec_subset(arr, len(arr)-1, 9))

方法二:非递归

import numpy as np
def dp_subset(arr, S):
    subset = np.zeros((len(arr), S+1), dtype=bool)
    subset[:, 0] = True # 0代表空间已经装满,所以赋值为 True
    subset[0, :] = False # 初始化箱子,空间没装值
    if arr[0] <= S:
    	subset[0, arr[0]] = True # 放入arr[0],这个地方肯定满足
    for i in range(1, len(arr)):
        for s in range(1, S+1):
            if arr[i]>s:
                subset[i, s] = subset[i-1, s]
            else:
                A = subset[i-1, s-arr[i]] #dp[i][j]目的就是求当前i,j的状态
                B = subset[i-1, s] #不选就是看前面那个字符,而且字符是累积状态
                subset[i, s] = A or B
    r, c = subset.shape
    return subset[r-1, c-1]
print(dp_subset(arr, 9))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值