题意:有30000个岛屿从左到右排列,给你一个n一个d,n代表有n个宝石分别,接下来n行表示每个宝石分别在哪个岛屿上,d代表你第一次从0开始跳跃到的位置,以后你每次可以从你的位置跳跃l-1,l,l+1的距离。

解题思路,其实以前做过一个类似的,他跳跃的步数其实很小,解设每次跳一步加以来也是(n+1)×n/2 = 30000差不多250左右,也就是说每次他最多也就会跳出来250种情况,所以,我们可以开dp[30010][500]再加一个偏移,这样记忆化搜索每个点,类似于树形dp从根节点找到一个最长的链,每次分三个叉,一个是l-1, l, l+1三个方向向下找。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>p;
const int N=4e4+5;
const int M=5e2+5;
const int mod=1e9+7;
int T,n,m,res,d;
int dp[N][M],a[N];
int dfs(int now,int pre) {
    if(pre==0||now>m)return 0;
    if(~dp[now][pre])return dp[now][pre];
    int ans=max({dfs(now+pre-1,pre-1),dfs(now+pre,pre),dfs(now+pre+1,pre+1)});
    return dp[now][pre]=ans+a[now];
}
int main() {
    memset(dp,-1,sizeof dp);
    cin>>n>>d;
    for(int i=1; i<=n; i++) {
        scanf("%d",&m);
        a[m]++;
    }
    printf("%d\n",dfs(d,d));
}