1.dp数组有关元素--路长和次数
2.递推公式

3.遍历顺序--最终影响的是路长,在外面
其次次数遍历,即这次路长所有情况都更新
最后,遍历次数自然就要遍历跳长
4.max时时更新


dp版本
#include<bits/stdc++.h>
using namespace std;
#define N 100011
typedef long long ll;
typedef pair<ll,int> pii;
int n,a,b,k,t;
ll w[110];
ll dp[110][110];
ll ma;
ll s;
int main() {cin>>t;while(t--){memset(dp,0,sizeof(dp));ma=0; cin>>n>>a>>b>>k;for(int i=1;i<=n;i++) cin>>w[i];dp[0][0]=0;for(int i=1;i<=min(n,k*b);i++)///路长为i {for(int j=1;j<=k;j++)///跳了j次 {for(int l=a;l<=b;l++)///上一次跳了l,即上次是路长i-l {if(i-l>=0){if(dp[i-l][j-1]==0)///dp==0说明没跳到,不能转移 {if(i==l&&j==1)///特例,就是dp[0][0] dp[i][j]=max(dp[i][j],dp[i-l][j-1]+w[i]);}else dp[i][j]=max(dp[i][j],dp[i-l][j-1]+w[i]);ma=max(ma,dp[i][j]);///记录max }}} }cout<<ma<<endl;}return 0;
}
2.记忆化版本--YYDS!
#include<bits/stdc++.h>
using namespace std;
#define N 100011
typedef long long ll;
typedef pair<ll,int> pii;
int n,a,b,k,t;
ll w[110];
ll dp[110][110];
ll ma;
ll s;
ll dfs(int l,int x)
{
if(l>n||x<0) return 0;///越界return 0
ll ma=0;
if(dp[l][x]!=-1) return dp[l][x];///记忆化剪枝
if(x==0)///没有次数就是没有未来,return 0
{return 0;
}
for(int i=a;i<=b;i++)
{ if(l+i<=n){ma=max(ma,dfs(l+i,x-1)+w[l+i]);///当前路长当前次数的ma }
}
return dp[l][x]=ma;///计的就算l长x次的极致MAX!
}
int main() {cin>>t;while(t--){cin>>n>>a>>b>>k;memset(dp,-1,sizeof(dp));for(int i=1;i<=n;i++) cin>>w[i];dfs(0,k);cout<<dp[0][k]<<endl;}return 0;
}