【算法】子串和(乘積)最大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 ])

 

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