您的位置:首页 > 其它

[Codeforces Round #286 DIV1A (CF506A)] Mr. Kitayuta, the Treasure Hunter

2017-01-24 11:34 417 查看

题意

有30001个小岛,K站在第0个岛上并跳到了第d个岛上。如果上一次跳的长度为l,接下来他只能往右跳l−1,l或l+1的长度。现在给出p个宝石的位置,询问K最多获得多少宝石。

题解

我们不去关心每一次跳的长度,只去关心这一次相比d的变化量Δl。因为这个−250<Δl<250(Σ250i=1=31125),于是我们可以开二维滚动数组进行dp,第二维开到500。

代码

/// by ztx
#include <cstdio>
#include <cstring>

#define  maxn  30010LL
#define  maxd  505LL

int n, L;
int p[maxn] = {0};
int f[maxn][maxd] = {0};

inline void MA(int&a,int b) {
if (b>a) a=b;
}

int main() {
int n,L,i,j,l,ans,len,maxp;
scanf("%d%d", &n, &L);
maxp = L;
for (i = 1; i <= n; i ++ ) {
scanf("%d", &j);
maxp = j;
p[j] ++ ;
}
memset(f,-1,sizeof f);
f[L][0+250] = p[L];
ans = 0;
for (i = L; i <= maxp; i ++ ) {
for (l = 0; l < maxd; l ++ ) {
if (f[i][l] == -1) continue;
MA(ans,f[i][l]);
len = L+l-250;
if (len+1>0 && i+len+1 <= 30000)
MA(f[i+len+1][l+1],f[i][l]+p[i+len+1]);
if (len > 0 && i+len <= 30000)
MA(f[i+len][l],f[i][l]+p[i+len]);
if (len-1 > 0 && i+len-1 <= 30000)
MA(f[i+len-1][l-1],f[i][l]+p[i+len-1]);
}
}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: