动态规划
1. 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
class Solution: #定义一个函数f(n),以第n个数为结束点的子数列的最大和,存在一个递推关系f(n) = max(f(n-1) + A[n], A[n]); def f(self,n,nums): if n==0: return nums[0] return max(self.f(n-1,nums)+nums[n],nums[n]) #将这些最大和保存下来后,取最大的那个就是,最大子数组和。 def maxSubArray(self, nums): nums_len=len(nums) result=float("-inf") for i in range(0,nums_len):#从0开始 result=max(self.f(i,nums),result) return result
2. 一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。
在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。
给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。
注意:本题相对原题稍作改动
示例 1:
输入: [1,2,3,1]
输出: 4
解释: 选择 1 号预约和 3 号预约,总时长 = 1 + 3 = 4。
示例 2:
输入: [2,7,9,3,1]
输出: 12
解释: 选择 1 号预约、 3 号预约和 5 号预约,总时长 = 2 + 9 + 1 = 12。
示例 3:
输入: [2,1,4,5,3,1,1,3]
输出: 12
解释: 选择 1 号预约、 3 号预约、 5 号预约和 8 号预约,总时长 = 2 + 4 + 3 + 3 = 12。
方法一:设计二维状态变量
第 1 步:设计状态
「状态」这个词可以理解为「记录了求解问题到了哪一个阶段」。
由于当前这一天有按摩师有两种选择:(1)接预约;(2)不接预约。但根据题意,今天是否接预约,是受到昨天影响的。为了消除这种影响,我们在状态数组要设置这个维度。
dp[i][0] 表示:区间 [0,i] 里不接受预约请求,并且下标为 i 的这一天不接受预约的最大时长;
dp[i][1] 表示:区间 [0,i] 里接受预约请求,并且下标为 i 的这一天接受预约的最大时长。
今天只和昨天的状态相关,依然是分类讨论:
今天不接受预约:或者是昨天不接受预约,或者是昨天接受了预约,取二者最大值,即:dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);
今天接受预约:只需要从昨天不接受预约转移而来,加上今天的时常,即:dp[i][1] = dp[i - 1][0] + nums[i]。
第 3 步:考虑初始化
从第 2 天开始,每天的状态值只与前一天有关,因此第 1 天就只好老老实实算了。好在不难判断:dp[0][0] = 0 与 dp[0][1] = nums[0];
class Solution: def massage(self, nums): nums_len = len(nums) if nums_len == 0: return 0 if nums_len == 1: return nums[0] dp = [[0 for i in range(2)] for j in range(nums_len)] dp[0][0] = 0 dp[0][1] = nums[0] for i in range(nums_len): # 今天不接受预约 dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]) # 今天接受预约 dp[i][1] = dp[i - 1][0] + nums[i] return max(dp[nums_len - 1][0], dp[nums_len - 1][1])
3.求最长上升子序列个数
找出以元素i结尾的最长递增子序列
每一次为i进行分配时,要检查前面所有的算法ai(i<x)
若ai小于ax,则说明ax可以跟在ai后形成一个新的递增子序列
否则,以ax结尾的递增子序列的最长长度为1
# F[1] = 1; # F[i] = max{1,F[j]+1|aj<ai && j<i} def f(nums): if len(nums)<=1: return len(nums) #存放各个字串的最长上升序列个数 men=[1 for i in range(len(nums))] for i in range(1,len(nums)): for j in range(0,i): if nums[j]<nums[i]: #跟新各个字串的最长上升序列个数 men[i]=men[j]+1 print(men) return max(men) list01=[6,2,1,3,7] print(f(list01))
posted on 2020-10-09 16:38 happygril3 阅读(129) 评论(0) 收藏 举报
浙公网安备 33010602011771号