思路:題目很直觀,用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;
}