【算法】子串和(乘积)最大DP

1. 最大子序和

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。nums中有正有负。

class Solution:
    def maxSubArray(self, nums):
        res = [0 for i in range(len(nums))]
        res[0] = nums[0]
        for i in range(1,len(nums)):
            res[i] = max(res[i-1]+nums[i], nums[i])
        return max(res)

2. 最大子序乘积

给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。nums中有正有负。

class Solution:
    def maxProduct(self, nums):
        max_res = [1 for i in range(len(nums))]
        min_res = [1 for i in range(len(nums))]
        max_res[0] = nums[0]
        min_res[0] = nums[0]
        for i in range(1, len(nums)):
            max_res[i] = max(max(max_res[i-1]*nums[i], min_res[i-1]*nums[i] ), nums[i])
            min_res[i] = min(min(max_res[i-1]*nums[i], min_res[i-1]*nums[i] ), nums[i])
        return max(max_res)

 

3. 合唱团

有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?

总结:列表a中按顺序取k个值,满足相邻两值位置差小于d,使得k个值乘积最大。(即最大子序乘积的变体。)

idea:DP, 维护两个数组,分别存最大值和最小值。

def maxmul(n,a, num_k, d):
    dpmax = [[0 for i in range(n)] for j in range(num_k)]
    dpmin = [[0 for i in range(n)] for j in range(num_k)]
    dpmax[0] = a #取1个学生,以第i个学生结尾的最大乘积即为该学生的值
    dpmin[0] = a
    for i in range(0,n):
        for k in range(1,num_k):#取k个学生,以第i个学生结尾的最大乘积
            for j in range(i-1,max(-1,i-d-1),-1):#不保证dp[k][i]真的取到了a中第i个元素,因此要遍历  
                dpmax[k][i] = max(dpmax[k][i], max(dpmax[k-1][j]*a[i], dpmin[k-1][j]*a[i]))
                dpmin[k][i] = min(dpmin[k][i], min(dpmax[k-1][j]*a[i], dpmin[k-1][j]*a[i]))
    return max(dpmax[-1])

4. 罪犯转移

C市现在要转移一批罪犯到D市,C市有n名罪犯,按照入狱时间有顺序,另外每个罪犯有一个罪行值,值越大罪越重。现在为了方便管理,市长决定转移入狱时间连续的c名犯人,同时要求转移犯人的罪行值之和不超过t,问有多少种选择的方式(一组测试用例可能包含多组数据,请注意处理)? 

总结:n个数存在列表val中,选择连续c个,使得c个数之和不超过t,求能选出多少组c?

def find(n, t, c, val):
    res = []
    res.append(sum(val[0:c]))
    for i in range(1,n-c+1):
        res.append(res[i-1]-val[i-1] + val[i+c-1])
    return len([i for i in res if i <=t ])

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章