Lanqiao3162:Frog(线性DP)

问题描述

一只名叫 “雾" 的小青蛙在回家的路上。路径长度为 N (1≤N≤100),沿途有许多昆虫。假设雾的原始坐标为 0。

雾可以静止不动,也可以向前跳跃若干个单位,跳跃的范围在 A∼B 之间。雾会把所有的昆虫吃掉,不管它在哪里,但它跳 K 次就会累了,跳不动了。给出了路径上每个位置昆虫的数量(总是小于 10000)。"雾" 最多能吃多少只昆虫?

注意,雾只能在 [0,N] 范围内跳跃,每当他跳跃时,他的坐标就会增加。

输入格式:输入第一行包含一个整数 T(1≤T≤10),表示测试用例的数量。

对于每个测试用例:第一行包含四个整数 N,A,B(1≤A≤B≤N≤100),K(1≤K≤N)。下一行包含 N 个整数 a1,a2,...,an(1≤ai≤1000),描述路径上每个位置昆虫的数量。

输出格式:每个测试用例:输出一行包含一个整数: 雾可以吃掉的最大昆虫数量。

输入样例:

1

4 1 2 2

1 2 3 4

输出样例:

6

解题思路

先明确题目给了两个限制:1.每次跳跃长度区间为[A,B],2.跳跃次数最多为K。

那么,可以定义当前所吃的虫子数量为dp[i][j]​ 为跳跃了 i 次后,当前处在 j 位置能吃到的最大昆虫数量。

列出状态转移方程为:dp[i][j] = max(dp[i-1][j-d]+a[j], dp[i][j]),其中d为这一次跳跃的距离

正常是对i从1到K遍历,对j从1到N遍历,但是考虑到,在i确定的情况下,j的范围是[A*i,B*i],同时为了避免越界,所以要用min(B*i+1,N+1)来限制j的范围。

同时还要考虑到 j-d>= 0这个限制

代码实现

def solve(N,A,B,K,a):
    dp = [[0]*(N+1) for _ in range(K+1)] 
    ans = 0
    for i in range(1,K+1):
        for j in range(A*i,min(B*i+1,N+1)):
            for d in range(A,B+1):
                if j-d<0:continue
                dp[i][j] = max(dp[i-1][j-d]+a[j], dp[i][j])
            ans = max(ans, dp[i][j])
    print(ans)
            

T = int(input())
for _ in range(T):
    N, A, B, K = map(int, input().split())
    a = [0] + list(map(int, input().split()))
    solve(N,A,B,K,a)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值