51nod 宝石猎人
2.0 2.0 2.0 秒/ 131 , 072.0 131,072.0 131,072.0 KB/ 40 40 40 分 / 4 4 4级题
食物(题目)
苏塞克岛是一个有着 30001 30001 30001个小岛的群岛,这些小岛沿着一条直线均匀间隔分布,从西到东编号为 0 0 0到 30000 30000 30000。众所周知,这些岛上有很多宝石,在苏塞克岛上总共有 n n n颗宝石,并且第i颗宝石位于岛 p p pi上。
小法正好到达 0 0 0号小岛上,他拥有卓越的跳跃能力,能根据以下规则在小岛之间向东重复跳跃:
首先,他会从 0 0 0号岛跳到 d d d号岛
此后,他会根据以下规则继续跳跃,L是上一次跳跃的长度,即,如果他上一次跳跃是从岛 p r e v prev prev岛 c u r cur cur, L = c u r − p r e v L= cur-prev L=cur−prev。他可以向东做一次长度为 L − 1 L-1 L−1, L L L或 L + 1 L+1 L+1的跳跃。即,他将会跳到岛 ( c u r + L − 1 ) , ( c u r + L ) (cur + L - 1), (cur + L) (cur+L−1),(cur+L)或 ( c u r + L + 1 ) (cur + L + 1) (cur+L+1)(如果这些岛存在)。一次跳跃的长度必须是正数,即,当L=1时,他不能做一次长度为 0 0 0的跳跃,如果没有有效的目的地,他将会停止跳跃。
小法将会在跳跃的过程中收集到过的岛上的宝石。我们要找到小法能收集的宝石的最大数。
样例解释:在第一个样例中,最优路径是 0 → 10 ( + 1 0 → 10 (+1 0→10(+1宝石 ) → 19 → 27 ( + 2 ) → 19 → 27 (+2 )→19→27(+2宝石 ) → . . . ) →... )→...
输入
输入的第一行是两个以空格隔开的整数
n
n
n和
d
(
1
≤
n
,
d
≤
30000
)
d (1 ≤ n, d ≤ 30000)
d(1≤n,d≤30000),分别表示苏塞克岛上的宝石数量和小法第一次跳跃的长度。
接下来
n
n
n行表示这些宝石的位置,第
i
i
i行(1 ≤ i ≤ n)包含一个整
p
p
pi
(
d
≤
(d ≤
(d≤
p
p
p1
≤
p
≤ p
≤p2
≤
.
.
.
≤
p
≤... ≤ p
≤...≤pn
≤
30000
)
≤ 30000)
≤30000),表示包含第
i
i
i颗宝石的小岛的编号。
输出
输出小法能收集的宝石的最大数
输入样例
4 10
10
21
27
27
输出样例
3
餐具(思路)
这道题是一道很明显的DP。
我们设 $f[i][j]$ 为跳跃 $j$ 个距离到达 $i$ 时,能收集的宝石的最大数。
状态转移方程易得。
甜品(伪代码)
循环 i -> d到ma
循环 j -> 0到500
如果 s[i,j] >= 0
k=j+d-250
循环 t -> -1到1
如果 k+t+i<=ma 且 t+k>0
s[ k+t+i,j+t ] = 较大值 (s[k+t+i,j+t] , s[i,j]+p[k+t+i])
ans = 较大值 ( ans , s[k+t+i][j+t] )
正菜(代码)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,d;
int p[30100];
int f[30100],s[30100][610];
long long ans;
int main()
{
memset(s,-1,sizeof(s)); //初始化
int x;
scanf("%d%d",&n,&d); //输入
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
p[x]++; //统计
}
s[d][250]=p[d]; //"250":易得每次d的偏移量约为±250
ans=s[d][250];
for(int i=d;i<=30010;i++) //位置
{
for(int j=0;j<=500;j++) //距离
{
if(s[i][j]>=0) //判断当前位置是否达到
{
int k=j-250+d; //预计距离
for(int t=-1;t<=1;t++) //如题
{
if(t+k>0&&k+t+i<=ma+1)
{
int c=k+t+i;
s[c][j+t]=max(s[i][j]+p[c],s[c][j+t]); //DP
ans=max(ans,(long long)s[c][j+t]); //答案求值
}
}
}
}
}
printf("%lld\n",ans); //输出
return 0;
}
(黑暗料理)
感谢大家支持!!!