比较简单的题,然而我老毛病又犯了,调错的时候容易上头= =
用dp[i][j]表示走到i,上一步走了j。但是直接做显然又T又M。由于速度大于零,所以设最大变化量为x,显然有(x+1)*x<=30000,发现速度的变化量比较小不到300,那么我们可以用dp[i][j]表示走到i,上一步走了j-300+d步。那么就可以直接转移了,方程显然,不过边界调了好久。
附代码
#include<bits/stdc++.h>
#define N 30010
using namespace std;
int dp[N*2][1010];
int va[N*2];
int n,d;
int main(){
memset(dp,-1,sizeof(dp));
scanf("%d%d",&n,&d);
dp[d][300]=0;
int add=0;
for(int i=0,a;i<n;i++){
scanf("%d",&a);
if(a==d) add++;
va[a]++;
}
int ans=0;
for(int i=0;i<=30000;i++){
for(int j=1;j<600;j++){
if(dp[i][j]!=-1){
if(j+d-301>0) dp[i+j-301+d][j-1]=max(dp[i+j-301+d][j-1],dp[i][j]+va[i+j-301+d]);
dp[i+j-300+d][j]=max(dp[i+j-300+d][j],dp[i][j]+va[i+j-300+d]);
dp[i+j-299+d][j+1]=max(dp[i+j-299+d][j+1],dp[i][j]+va[i+j-299+d]);
}
ans=max(ans,dp[i][j]);
}
}
printf("%d\n",ans+add);
return 0;
}