一个连续子数组最大和的变种,修改一个数——动态规划解法。

题目描述:第一行输入一个整数t,代表询问次数。对于每次询问,输入两行;第一行输入两个正整数n和k,代表数组的大小,以及小红可以修改的元素。第二行输入n个正整数a_i,代表小红拿到的数组。输出t行,每行输出一个整数,代表连续子数组的最大和。
测试样例:

请输入询问次数t: 3
请输入数组大小n和可修改元素k: 5 10
请输入数组元素,空格分隔: 5 -1 -5 -3 2
请输入数组大小n和可修改元素k: 2 -3
请输入数组元素,空格分隔: -5 -2
请输入数组大小n和可修改元素k: 6 10
请输入数组元素,空格分隔: 4 -2 -11 -1 4 -1
15
-2
15

动态规划解法:

def max_subarray_sum(arr, k):
    # 以i位置为结尾,且没使用修改的最大子数组和
    dp_no = [arr[0]]
    # 以i位置为结尾,且使用了修改的最大子数组和
    dp_has = [k]
    
    max_sum = max(dp_no[0], dp_has[0])
    n = len(arr)
    for i in range(1, n):
        dp_no.append(0)
        dp_has.append(0)
        # 计算dp_no[i], 只能从dp_no[i-1]得到
        if dp_no[i-1]<0:
            dp_no[i] = arr[i]
        else: 
            dp_no[i] = arr[i] + dp_no[i-1]
        # 计算dp_has[i],两种情况
        # 第一种,i-1已经用过了,从dp_has[i-1]转移状态
        if dp_has[i-1]<0:
            dp_has[i] = arr[i]
        else:
            dp_has[i] = arr[i] + dp_has[i-1]
        # 第二种, i位置使用, 从dp_no[i-1]转移状态
        temp = 0
        if dp_no[i-1]<0:
            temp = k
        else:
            temp = k + dp_no[i-1]
        # 计算两种情况中的最大值
        dp_has[i] = max(dp_has[i], temp)

        # 更新max_sum
        max_sum = max(max_sum, dp_no[i], dp_has[i])
    return max_sum


if __name__ == "__main__":
    t = int(input("请输入询问次数t: "))
    results = []
    
    for _ in range(t):
        n, k = map(int, input("请输入数组大小n和可修改元素k: ").split())
        arr = list(map(int, input("请输入数组元素,空格分隔: ").split()))
        result = max_subarray_sum(arr, k)
        results.append(result)
    
    for res in results:
        print(res)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值