动态规划:
一维动态规划:
目前我们所见到的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