动态规划:
一维动态规划:
目前我们所见到的DP问题都是1D的,让我们看一下其他例子:
问题描述1:给定n,找到不同的n写成1,3,4相加的方法
例如:n=5,答案是6
答案:公式:Dn = Dn-1 +Dn-3 +Dn-4
D[0] = D[1]=D[2] D[3]=2
for (i=4;i<=n;i++){
D[i] = D[i-1]+D[i-3]+D[i-5]
}
问题描述2:
假设你是一个职业拿钱犯,你打算拿一个街道的钱。每个房子里有定数量的钱。限定你的唯一条件是相邻的房子安保系统是相连的,如果拿相邻的房子就会惊动警察。
给定一个非负整数的列表代表每个房子当中的钱,计算在不惊动警察的情况下你可以拿到最多的钱。
答案:定义公式Yes(i) = 当前抢这个房子得到的最大值 No(i)=当前不抢这个房子得到的最大值
得到规律: Yes(i) = No(i-1)+a[i]
No[i] =max(Yes[i-1], No[i-1])
Yes[1] = a[1] Yes[2] = No[1]+a[2]
No[1] = 0 No[2] = max(Yes[1],No[1])
result: max(Yes[i], No[i])
def job(nums):
n = len(nums)
dp=[ [0]*2 for _ in range(n+1)]
for i in range(1, n+1):
dp[i][0] = max(dp[i-1][0], dp[i-1][1])
dp[i][1] = dp[i-1][0]+nums[i-1]
return max(dp[n][0], dp[n][1])
def job1(nums):
yes, no = 0, 0
for i in nums:
yes, no = i+no, max(yes, no)
return max(no, yes)
nums=[2,7,8,3,1]
print(job1(nums))
问题描述3:
一个公司领导和员工为树状结构排列,一个人去公司拿钱,拿钱的规则是拿了一个人的钱,那么这个人的领导和下属就不能再拿了,一共能拿多少钱?
Yes[i] = 所有下属的和No[i-1] + a[i]
No[i] = 所有的和max(Y[i-1], No[i-1])
问题描述4:
假定给定一块n*2的地板,瓷砖的大小为1*2,计算需要一共有铺满长廊的方式。瓷砖可以水平放置:1*2.也可以数值2*1.
F[n] = F[n-1] + F[n-2]
问题描述5:
有一个楼梯,每次可以走1层或者2层,cost数组表示每一层所需要花费的值。可以从0节或者1节台阶开始走,一旦交了过路费,可以上1个台阶或者两个台阶,计算花费最少费用登顶。
dp[i]代表到达第I层所需要的花费
dp[i] = min(dp[i-2] + cost[i-2], dp[i-1]+cost[i-1])
def minCostClimbing(cost):
n = len(cost) + 1
dp = [0] * n
for i in range(2, n):
dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2])
return dp[n-1]
nums = [1,100,1,1,1,100,1,1,100,1]
print(minCostClimbing(nums))
问题描述6:
如果一个编码1-A,2-B,..., 26-Z,问给一个字符串,有几种解码形式。
def numDecoder(str):
if str == "" or str[0]=="0": return 0
dp =[1, 1]
for i in range(2, len(str)+1):
result = 0
if 10 <= int(str[i-2:i]) <=26:
result = dp[i-2]
if str[i-1] != "0":
result += dp[i-1]
dp.append(result)
return dp[len(str)]
str = "120"
print(numDecoder(str))
问题描述7:
给定n:用1.。。n个数字来表达Binary Search Tree,问有多少种表达方式
公式为从1到n求(Ti-1*Tn-i)的和,就是出名的CatalonNumber
def NumTree(num):
if num < 2:
return num
sol = [0] * (num + 1)
sol[0] = sol[1] = 1
for i in range(2, num + 1):
for left in range(0, i):
sol[i] += sol[left] + sol[i-1-left]
return sol[num]
print([NumTree(i) for i in range(1,10)])
问题描述8:
给定一个数组,寻找连续子数组的元素乘积最大:
def maxProduct(nums):
if len(nums)==0:
return 0
maximum = minimum = result = nums[0]
for i in range(1, len(nums)):
maximum, minimum = max(maximum * nums[i], minimum * nums[i], nums[i]),\
min(maximum * nums[i], minimum * nums[i], nums[i])
result = max(result, maximum)
return result
nums = [2, 5, 6, -2, 8, 3]
print(maxProduct(nums))
来源:https://www.cnblogs.com/lvxiaoning/p/12019612.html