2 条题解
-
1
在题解开始之前,先让我%%%%%一下@尚轩好大神,相比孙老板的dp,他的代码更加容易理解(
也更好码)
那么首先让我们来读一下题 有两只青蛙A,B,他们都要跳过n个石子。石子间的距离有长有短,有些甚至超过了青蛙们的弹跳能力,怎么办呢?他们有一个超级大宝贝
助跳器
这个助跳器非常强大,可以让青蛙的弹跳能力由m变为k。而根据题中数据保证,有了助跳器的青蛙可以一路跳到终点! 那么该怎么决定青蛙拿到弹跳器的顺序呢?
先看看题目的样例说明
青蛙 𝐴 先走到第二颗石头(位置 10),此时将助跳器传递给青蛙 𝐵;青蛙 𝐵 跳 到终点(位置 20)再将助跳器传递给 𝐴,𝐴 跳到终点。
注意:若 𝐴 直接跳到终点,则此时助跳器传递不到 𝐵(因为两青蛙此时的距离 大于 𝑞), 𝐵 无法抵达终点。
明显的,如果我们一开始先让a跳,是非常难以考虑的。代码的执行有先后,如果你不知道b在没有助跳器的情况下能跳到什么位置,那你也决定不了a要跳到哪个位置(a需要给b助跳器,条件是a与b距离小于q) 所以,我们要反其道而行之,先让b跳到他的极限 这个代码实现非常简单,如果下一块石头和他脚踩的距离小于m就跳过去,就不贴出来了; b跳完了,那么现在看看a 对于持有助跳器的a来说,他想跳到哪里就跳哪里,重要的是他需要给b助跳器,明显的,他所能跳到的最远距离是和b相差小于等于q的距离。我们把他跳过去,就让他把助跳器给过去。 此时拿有助跳器的b,操作上是可以等同a的,他也可以跳到任意位置,重要的是失去助跳器后的a能跳到哪个位置
那么讲到这里,其实大家应该也差不多懂了吧,下面是核心代码;
void bs() { while(y<n&&b[y+1]-b[y]<=m) y++; if(y==n)return ; while(x<n&&a[x+1]-b[y]<=q) x++; ans++; as(); }
最后%%%%一下葛雨墨大神,上能codding,下能文能理,在考试中取得nb的成绩。
-
0
孙老板的代码 (dp),能看懂就看看吧 ,
没准以后可能大概也许或许会来注释#include <bits/stdc++.h> using namespace std; const int maxn = 1005; int a[maxn], b[maxn], dp[maxn][maxn][2]; int main(){ //freopen("pass.in","r",stdin); //freopen("pass.out","w",stdout); int n, m, k, q; cin >> n >> m >> k >> q; for(int i = 1; i <= n; i++){ cin >> a[i]; } for(int i = 1; i <= n; i++){ cin >> b[i]; } a[n+1] = a[n]; b[n+1] = b[n]; memset(dp, 0x3f, sizeof dp); dp[0][0][0] = 0; dp[0][0][1] = 1; for(int step = 0; step <= 2 * n; step++){ for(int j = 0; j <= min(n, step); j++){ int i = step - j; if(i > n) continue; for(int k = 0, r = 0; r <= 3; k++, r++){ // 枚举第三维时,在原地转移 4 次,这样 0 1 都被互相求 min k = r % 2; if(dp[i][j][k] >= 1e9) continue; if(abs(a[i] - b[j]) <= q) dp[i][j][k^1] = min(dp[i][j][k^1], dp[i][j][k] + 1); if(k == 0){ dp[i+1][j][k] = min(dp[i+1][j][k], dp[i][j][k]); if(b[j+1] - b[j] <= m){ dp[i][j+1][k] = min(dp[i][j+1][k], dp[i][j][k]); } }else{ dp[i][j+1][k] = min(dp[i][j+1][k], dp[i][j][k]); if(a[i+1] - a[i] <= m){ dp[i+1][j][k] = min(dp[i+1][j][k], dp[i][j][k]); } } } } } cout << min(dp[n][n][0], dp[n][n][1])<< endl; return 0; }
- 1
信息
- ID
- 785
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 7
- 标签
- (无)
- 递交数
- 35
- 已通过
- 8
- 上传者