第一节 Dynamic Programming
1、定义
- 1、问题目标
- 2、状态的定义 opt[n]
- 3、状态转移方程: opt[n]=best_of(opt[n-1],opt[n-2],…)
2、问题1:最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
代码
def maxSubArray(nums):
if len(nums)==1:
return nums[0]
max_ret=nums[0]
cur_max=last_max=nums[0]
for i in range(1,len(nums)):
if last_max+nums[i]<nums[i]:
cur_max=nums[i]
else:
cur_max=last_max+nums[i]
if cur_max> max_ret:
max_ret=cur_max
last_max=cur_max
return max_ret
a=maxSubArray([1,-1,4,-3,5])
print(a)
3、问题2:最大上升子序列
- L(j):在j位置,以这个位置得元素结尾的最长的字串是多少。
- 筛选条件1:前面的值比他小的
- 筛选条件2:最大的L(j)
- 将比它小的L(j) 再加1,为当前最大上升子序列
代码
def Lenghth(num):
if len(num)<=1:
return len(num)
mem=[1 for _ in range(len(num))]
print("mem:",mem)
for j in range(1,len(num)):
for i in range(0,j):
if num[i]<num[j]:
#每次对于j前面的元素,对比它的最长子序列和当前最长的子序列,选择最大的
mem[j]=max(mem[j],mem[i]+1)#保存每个位置最长的上升子序列
return max(mem)
# a=maxSubArray([3,4,5,-15,-3])
a=Lenghth([1,3,2,5,1,6])
print(a)
4、问题3:零钱兑换
代码
def coinChange(coins,amount):
if amount==0:
return 0
if len(coins)==0:
return -1
if len(coins)==1 and coins[0]>amount:
return -1
mem=[-1 for _ in range(amount+1)]
mem[0]=0
for i in range(1,amount+1):
cur_min=amount+1
for c in coins:
if c<=i:
cur_min=mem[i-c] if mem[i-c]<cur_min else cur_min
mem[i]=cur_min+1 if cur_min<amount+1 else amount+1
if mem[-1]== amount+1:
return -1
else:
return mem[-1]
a=coinChange([1,7,8,9],14)
print(a)
5、问题5:0-1背包问题
代码
def knapsack(w,v,c):
mem=np.zeros((len(w)+1,c+1))#定义存储空间并初始化
for i in range(1,len(w+1)):
for j in range(1,c+1):
if w[i-1]<=j:
mem[i,j]=max(mem[i,j],mem[i-1,j],mem[i-1,j-w[i-1]]+v[i-1])
else:
mem[i,j]=mem[i-1,j]
return mem
6、问题6:编辑距离