动态规划 之 枚举型
文章目录
- 枚举类型
- 青蛙吃虫
- 选择与不选择问题
动态规划的题目
,主要分为枚举类型和这个是否选择的两种题型
- 枚举类型:本质上,就是当前的状态由多个先前状态可以转移而来,常常多于两个,我们这时候就得使用循环进行枚举先前的最优的状态(
类似于多选择问题
) - 选择与不选择类型:本质上就是枚举类型的选择策略的减少化,我们常常对于当前的元素,有选择以及不选择两种策略(
有点类似于二分选择
)
枚举类型
青蛙吃虫
思路分析:
- 首先确定优化的值,也就是吃掉的最大的昆虫数量
- 确定条件,最多只能跳
K
次,并且只能在1-N
范围内跳动,每次跳动还只能在A-B
范围内 - ==》由于有次数,位置两个限制条件,所以定义
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示在第
i
次跳动在位置j
所能吃掉的最大的昆虫数量,那么dp[i][j]
的值就是它先前的在第i-1次
所有能够到达它的位置的地方的dp[i-1][p]
,到达dp[i][j]
之后吃掉num[j]
与dp[i][j]
的值的较大值 - 在这里,我们会枚举可能的步数
s:A-B
,当当前的位置j-s<0
那么直接就跳过,否则就可以由转移方程得到,那么就会有一个问题?是否可达?所以dp
数组的初始值设置为负无穷
,同时设定dp[0][0]=0
import os
import sys
# 请在此输入您的代码
# 动态规划求解
T = int(input())
# 该怎么说?dp[i][j]定义为 在第i次跳跃的时候,处于位置j所能够吃的最多的昆虫数目
for _ in range(T):
N,A,B,K = map(int,input().split())
num = [0] + list(map(int,input().split()))
dp = [[-float('inf')]*(N+1) for _ in range(K+1)]
dp[0][0] = 0
ans = 0
for i in range(1,K+1):
for j in range(1,N+1):
for p in range(A,B+1):
if j - p < 0:
break
dp[i][j] = max(dp[i][j],dp[i-1][j-p]+num[j])
ans = max(ans,dp[i][j])
print(ans)