今天是要将被吊打进行到底了,真是有勇气往下做,这题看着题目挺简单的样子,一上来思路就是dp或者bfs,本渣水平低,觉得dp要开30000*30000的数组,这势必是要MLE了,于是转而用bfs,bfs好写归好写,但是容易TLE,我第二个sample就过不去了,不造为啥一直跑根本停不下来啊。。
这题的正解应该是dp吧,首先要防止MLE,就是需要注意他的状态,每次跳跃能力的变化幅度很小,如果起初是1,每次跳跃距离+1的话,n*(n+1)/2>30000;n<800,最多开1600即可了,存储时可以设int k=j-d+800,不理解那些大神们为啥敢开400啊500啊,我试过不会爆掉。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
int b[30005][1600];
int a[30005];
int n,d,maxn;
int dp(int i,int j)
{
int k=j-d+800;
if(i>maxn) return 0;
else if(!j) return 0;
else if(b[i][k]>=0) return b[i][k];
else
{
int q=max(dp(i+j+1,j+1),dp(i+j,j));
q=max(q,dp(i+j-1,j-1));
return b[i][k]=a[i]+q;
}
}
int main()
{
maxn=0;
scanf("%d %d",&n,&d);
memset(a,0,sizeof(a));
memset(b,-1,sizeof(b));
for(int i=0;i<n;i++)
{
int t;
scanf("%d",&t);
if(maxn<t) maxn=t;
a[t]++;//这个岛存在宝石数量,
}
printf("%d\n",dp(d,d));
return 0;
}