思路:题目很直观,用dp[i][j]表示走到第i个island,jump值为j时的最优值,但是状态的数据量均为30000,超内存。
由于d每次最多只能改变1,考虑d改变的最大幅度。设到达终点需跳x次,则有:
当d = 1时,x < 250。d可以正向/负向改变250,所以使用500的数组存储即可。
dp[i][j]表示到达第i个island,jump值为d + (j - 250)时的最优解,求解时注意状态的有效性即可。
代码如下:
#include <cstdio>
#include <cstring>
using namespace std;
#define N 30005
#define max(a, b) (a) > (b) ? (a) : (b)
int dp[N][505], pos[N], gem[N];
int main(){
int n, d, max_pos = 0, ans = 0;
scanf("%d %d", &n, &d);
for(int i = 0; i < n; ++i){
scanf("%d", &pos[i]);
gem[pos[i]] ++;
if(pos[i] > max_pos)
max_pos = pos[i];
}
memset(dp, -1, sizeof(dp));
dp[d][250] = 0;
for(int i = d; i <= max_pos; ++i){
for(int j = 0; j <= 500; ++j){
if(dp[i][j] == -1)
continue;
dp[i][j] += gem[i];
if(dp[i][j] > ans)
ans = dp[i][j];
for(int k = j - 1; k < j + 2; ++k){
int next = i + k - 250 + d;
if(k == 0 || next <= i || next > max_pos)
continue;
dp[next][k] = max(dp[next][k], dp[i][j]);
}
}
}
printf("%d\n", ans);
return 0;
}