CodeForces 506 Div.1 A. Mr. Kitayuta, the Treasure Hunter

来源:互联网 发布:edf调度算法实现 编辑:程序博客网 时间:2024/06/02 04:12

A. Mr. Kitayuta, the Treasure Hunter
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

The Shuseki Islands are an archipelago of 30001 small islands in the Yutampo Sea. The islands are evenly spaced along a line, numbered from 0 to 30000 from the west to the east. These islands are known to contain many treasures. There are n gems in the Shuseki Islands in total, and the i-th gem is located on island pi.

Mr. Kitayuta has just arrived at island 0. With his great jumping ability, he will repeatedly perform jumps between islands to the east according to the following process:

  • First, he will jump from island 0 to island d.
  • After that, he will continue jumping according to the following rule. Let l be the length of the previous jump, that is, if his previous jump was from island prev to island cur, let l = cur - prev. He will perform a jump of length l - 1l or l + 1 to the east. That is, he will jump to island (cur + l - 1)(cur + l) or (cur + l + 1) (if they exist). The length of a jump must be positive, that is, he cannot perform a jump of length 0 when l = 1. If there is no valid destination, he will stop jumping.

Mr. Kitayuta will collect the gems on the islands visited during the process. Find the maximum number of gems that he can collect.

Input

The first line of the input contains two space-separated integers n and d (1 ≤ n, d ≤ 30000), denoting the number of the gems in the Shuseki Islands and the length of the Mr. Kitayuta's first jump, respectively.

The next n lines describe the location of the gems. The i-th of them (1 ≤ i ≤ n) contains a integer pi (d ≤ p1 ≤ p2 ≤ ... ≤ pn ≤ 30000), denoting the number of the island that contains the i-th gem.

Output

Print the maximum number of gems that Mr. Kitayuta can collect.

Sample test(s)
input
4 1010212727
output
3
input
8 8919283645556678
output
6
input
13 788916171718212324242630
output
4
Note

In the first sample, the optimal route is 0  →  10 (+1 gem)  →  19  →  27 (+2 gems)  → ...

In the second sample, the optimal route is 0  →  8  →  15  →  21 →  28 (+1 gem)  →  36 (+1 gem)  →  45 (+1 gem)  →  55 (+1 gem)  → 66 (+1 gem)  →  78 (+1 gem)  → ...

In the third sample, the optimal route is 0  →  7  →  13  →  18 (+1 gem)  →  24 (+2 gems)  →  30 (+1 gem)  → ...


题目大意

        有 n 个小岛,所有小岛排成东西方向的一行。所有小岛的位置为0到30000的一个整数,你的初始位置是0。你从左往右走,第一次向右跳到位置 d,接下来每次,你上次跳的距离是 l,则这次你可以跳的距离是l-1、l、l+1。你每次都必须往右跳,不能往左跳。询问你从左走到右面最多能经历几个岛屿。

数据范围

        小岛数不超过30000个,初始跳的距离不超过30000。

思路

        标准的dp问题,开个二维数组 b[i][j] 储存当前位置是 i ,上一步跳的距离是 j 时能达到的最多岛屿数。最后所求答案为 b[d][d]。

        但可以发现30000*30000的数组会超内存,所以需要进一步处理。假设初始跳的距离是 dd 则到达最后一个岛屿的时候即使每次都多跳1m也不会超过 dd+x(x 为跳的步数),总距离不超过30000。(dd+x+x)*x/2<=30000,当 dd 取最小值 1 时 x 可以取到最大值,可以计算出来此时 x 不超过300,我们就设 d[i][j] ,当前位置是 i,上一步跳的是 dd+j,所需大小为30000*300。

        此时又会产生问题,就是j可能是负数。所以我们可以设 300 为 0,299 为 -1 ,301为1。设 d[i][j] ,当前位置是 i,上一步跳的是 dd+j-300,所需大小为30000*600。初始时为 b[d][300]。

AC代码

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int n,dd;int a[30001];int b[30001][600];int ma;int f(int x,int d){    if(b[x][d] != -1) return b[x][d];    int ret = 0;    for(int i = -1 ;i<=1;i++){        if(x+d+dd-300+i<=ma && i+dd+d-300 > 0){            ret = max(ret,f(x+d-300+dd+i,d+i));        }    }    //cout<<x<<" "<<d<<" "<<ret + a[x]<<endl;    return b[x][d] = ret + a[x];}void solve(){    memset(a,0,sizeof(a));    memset(b,0xff,sizeof(b));    int t;    for(int i = 0;i<n;i++){        scanf("%d",&t);        a[t] ++;    }    ma = t;    printf("%d\n",f(dd,300));}int main(){#ifdef ARTHUR_YANGfreopen("in.txt","r",stdin);#endif // ARTHUR_YANG    int t;    while(~scanf("%d%d",&n,&dd)){        solve();    }    return 0;}

94748122015-01-19 14:09:27qwsqwaA - Mr. Kitayuta, the Treasure HunterGNU C++Accepted155 ms72400 KB

0 0
原创粉丝点击