P10914 [蓝桥杯 2024 国 B] 跳石
P10914 [蓝桥杯 2024 国 B] 跳石头
题目描述
小明正在和朋友们玩跳石头的小游戏,一共有 n n n 块石头按 1 1 1 到 n n n 顺序排成一排,第 i i i 块石头上写有正整数权值 c i c_i ci。
如果某一时刻小明在第 j j j 块石头,那么他可以选择跳向第 j + c j j + c_j j+cj 块石头(前提 j + c j ≤ n j + c_j \le n j+cj≤n)或者跳向第 2 j 2j 2j 块石头(前提 2 j ≤ n 2j \le n 2j≤n),没有可跳跃的目标时游戏结束。
假如小明选择从第 x x x 块石头开始跳跃,如果某块石头有可能被小明经过(“经过” 指存在某一时刻小明在这个石头处),则将这块石头的权值纳入得分集合 S x S_x Sx,那么小明从第 x x x 块石头开始跳跃的得分为 ∣ S x ∣ |S_x| ∣Sx∣。
比如如果小明从第 x x x 块石头出发,所有可能经过的石头上的权值分别为 5 , 3 , 5 , 2 , 3 5,3,5,2, 3 5,3,5,2,3,那么 S x = { 5 , 3 , 2 } S_x = \{5, 3, 2\} Sx={5,3,2} 得分为 ∣ S x ∣ = 3 |S_x| = 3 ∣Sx∣=3。小明可以任选一块石头开始跳跃,请求出小明最多能获得的分数。
输入格式
输入共 2 2 2 行。
第一行为一个正整数 n n n。
第二行为 n n n 个由空格分开的正整数 c 1 , c 2 , ⋯ , c n c_1, c_2,\cdots, c_n c1,c2,⋯,cn。
输出格式
输出共 1 1 1 行,一个整数表示答案。
输入输出样例 #1
输入 #1
5
4 3 5 2 1
输出 #1
4
说明/提示
【样例说明】
从第一块石头出发得分最多,路径有以下几种:
- 1 1 1 号 → 5 \to 5 →5 号:选择从 1 1 1 号跳到 1 + c 1 = 5 1 + c_1=5 1+c1=5 号。
- 1 1 1 号 → 2 \to 2 →2 号 → 5 \to 5 →5 号:第一次选择从 1 1 1 号跳到 2 × 1 = 2 2 \times 1=2 2×1=2 号,第二次选择从 2 2 2 号跳到 2 + c 2 = 5 2 + c_2 = 5 2+c2=5 号。
- 1 1 1 号 → 2 \to 2 →2 号 → 4 \to 4 →4 号:第一次选择从 1 1 1 号跳到 2 × 1 = 2 2 \times 1=2 2×1=2 号,第二次选择从 2 2 2 号跳到 2 × 2 = 4 2 \times 2 = 4 2×2=4 号。
所以所有可能经过的石头的权值的集合为 S 1 = { c 1 , c 2 , c 4 , c 5 } = { 4 , 3 , 2 , 1 } S_1 = \{c_1, c_2, c_4, c_5\} = \{4, 3, 2, 1\} S1={c1,c2,c4,c5}={4,3,2,1},得分为 ∣ S 1 ∣ = 4 |S_1| = 4 ∣S1∣=4。
【评测用例规模与约定】
对于
20
%
20\%
20% 的评测用例,保证
n
≤
20
n \le 20
n≤20。
对于
100
%
100\%
100% 的评测用例,保证
n
≤
40000
n \le 40000
n≤40000,
c
i
≤
n
c_i \le n
ci≤n。
题解:总觉得题说的有点问题,不过看样例还是能get,找出所有可能S值,输出个数。
运用了bitset和在其中的count函数,注意此处的count用于统计bs中1的个数(因为除了计算步数外权值的作用不大,只需要用bitset统计是否走过就ok)
#include<bits/stdc++.h>
using namespace std;
const int MAXN=40005;
int c[MAXN], n, ans;
bitset<MAXN> bs[MAXN];
int main() {
cin>> n;
for (int i=1;i<=n;i++) cin>> c[i];
for (int i=n;i>=1;i--) {
bs[i][c[i]]=1;
if (i+c[i]<=n) bs[i]|=bs[i+c[i]];
if (i*2<=n) bs[i]|=bs[i*2];
ans=max(ans, (int)bs[i].count());
}
cout<<ans;
return 0;
}