题意:有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)); }