Python与动态规划(实例篇一)
实例一
问题:最大连续和
给出一个长度为n的序列A1,A2,…,An,求最大连续和。换句话说,要求找到1<=i <= j<=n,使得Ai+Ai+1+..+Aj尽量大
举例
输入:
1 -2 3 10 -4 7 2 -5
输出:
18==( 3 10 -4 7 2 )
提示
b[i] = { b[i-1] + a ,b[i-1] > 0
{ a ,b[i-1] < 0
思路有很多
粗暴简单的动态规划
def maxsum(inner_list):
Max,temp=inner_list[0],0
for i in inner_list:
if temp<0:temp=i #更新起点
else:temp+=i
Max=max(temp,Max)
return Max
上述做法不难理解,递增消失则更新起点,与此同时比较最大值
引申做法->分治法
划分:元素二分
递归:分别求完全左半和完全右半最大连续和序列
合并:求出起点位于左半,终点位于右半的序列。先寻找最佳起点,再寻找最佳终点
注意代码的简洁性
def maxsum2(inner_list,low,high):
if high==low+1:return inner_list[low] #函数出口
mid=low+(high-low)//2 #注意取整
imax=max(maxsum3(inner_list,low,mid),maxsum3(inner_list,mid,high)) #递归
#注意,为了使两头序列能够相加起来,左序列从最右边开始,右序列从最左边开始
iSum,iL=0,inner_list[mid-1]
for i in reversed(inner_list[:mid]): iSum,iL=i+iSum,max(iSum,iL)
iSum,iR=0,inner_list[mid]
for i in inner_list[mid:]: iSum,iL=i+iSum,max(iSum,iL)
return max(imax,iL+iR)
另一个思路
显然 Ai+……+Aj=Sj – Si-1, 其中Sn=A1+……An
def maxsum2(inner_list):
Sn,temp,Max=[],0,inner_list[0]
for i in inner_list:
temp+=i
Sn.append(temp)
#注意此处,造成了一些多余的计算,为了好看
for i in itertools.permutations(Sn,2): Max=max(Max,abs(i[0]-i[1]))
return Max
其实这个问题并不难,读者可以往深层次去挖掘,比如说后续的从n个数中找到m个连续数和的最大值。尤其是要理解方法二中的状态转移。
如果您看到这篇文章有收获或者有不同的意见,欢迎点赞或者评论。
python群:190341254
丁。