列表

详情


NC232853. 宝藏猎人

描述

在S群岛有30001座小岛,它们排列在一条直线上,编号从西到东为0到30000。在这些岛上一共有n个宝石,其中第i个在编号为p_i的岛上。

小K在编号为0的岛上,他想利用他强大的弹跳能力,按以下规则不断向东跳:

首先,他会从0跳到d
之后,他会按下述规则跳:设上一次小K从prev跳到cur,令,下一次他将向东跳到的其中一个岛(若存在)。他跳的距离必须是正整数,即当时他跳的长度不能为0。若没有符合条件的目的地,他将停止向东跳。

小K会在向东跳的同时收集岛上的宝石。求出小K最多能收集多少宝石。

输入描述

第一行输入两个整数n,d (),表示宝石的数量和小K第一次跳的距离。
接下来的n行,每行一个整数。第i行的数p_i ()表示第i个宝石所在的岛的编号。

输出描述

输出一个整数,表示小K能收集的宝石的最大数量。

示例1

输入:

4 10
10
21
27
27

输出:

3

说明:

路径为:0 -> 10 (+1) -> 19 -> 27 (+2) ->...

示例2

输入:

8 8
9
19
28
36
45
55
66
78

输出:

6

说明:

路径为:0 -> 8 -> 15 -> 21 -> 28 (+1) -> 36 (+1) -> 45 (+1) -> 55 (+1) -> 66 (+1) -> 78 (+1) ->...

示例3

输入:

13 7
8
8
9
16
17
17
18
21
23
24
24
26
30

输出:

4

说明:

路径为:0 -> 7 -> 13 -> 18 (+1) -> 24 (+2) -> 30 (+1) ->...

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 310ms, 内存消耗: 120460K, 提交时间: 2022-11-21 17:00:01

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e4+10,M=300;
ll dp[N][510],w[N];
int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int len,d;
    cin>>len>>d;
    for(int i=1;i<=len;i++){
        int x;
        cin>>x;
        w[x]++;
    }
    memset(dp,-0x3f,sizeof dp);
    dp[d][260]=w[d];
    ll ans=w[d];
    for(int i=1;i<=N-10;i++){
        for(int j=-250;j<=250;j++){
            int p=d+j,z=260+j;
            if(p<=0) continue;
            if(p>i) continue;
            dp[i][z]=max(dp[i][z],dp[i-p][z+1]+w[i]);
            dp[i][z]=max(dp[i][z],dp[i-p][z]+w[i]);
            if(p) dp[i][z]=max(dp[i][z],dp[i-p][z-1]+w[i]);
            ans=max(ans,dp[i][z]);
        }
    }
    cout<<ans;
}

C++(clang++ 11.0.1) 解法, 执行用时: 143ms, 内存消耗: 60392K, 提交时间: 2022-10-06 15:27:47

#include<bits/stdc++.h>
#define qq 30005
#define pq 255
using namespace std;
int a[qq],dp[qq][pq<<1],n,d,x;
int main(){
    cin>>n>>d;
    for(int i=1;i<=n;++i) scanf("%d",&x),++a[x];
    memset(dp,-0x3f,sizeof(dp));
    dp[d][pq]=a[0]+a[d];
    for(int i=0;i<=30000;++i){
        for(int j=-250;j<=250;++j){
            if(i-(d+j)<0 || i-(d+j)>30000) continue;
            dp[i][j+pq]=max(dp[i][j+pq],max(dp[i-(d+j)][j+pq],max(dp[i-(d+j)][j-1+pq],dp[i-(d+j)][j+1+pq]))+a[i]);
        }
    }
    int ans=0;
    for(int i=0;i<=30000;++i)for(int j=-250;j<=250;++j)ans=max(ans,dp[i][j+pq]);
    cout<<ans;
    return 0;
}

上一题