洛谷P1095 绝地武士的逃离

好吧原题是守望者的逃离,我强行改了一波题面,因为信仰=-=(?

May the force be with us.

绝地跑步速度为17m/s,但无法逃离荒岛。绝地的原力恢复速度为4点/s,只有处在原地才能恢复
绝地神行术需消耗10点原力,使用神行术,一秒可移动60m
已知绝地的魔法初值为M,所在的初始位置与岛的出口之间的距离为S,岛沉没的时间为T,计算绝地用多久才能逃离荒岛,若不能逃出,输出守望者剩下的时间走的最远的距离

当不能逃出时,我们要求最远距离
那么我们将子问题化为f[i]表示在第i秒时的最远距离
因为是求当前状态的最远距离,很显然的要用当前状态的所有前置状态转移
对于每一秒,绝地大师有3中可能行动:
1.停在原地恢复原力
2.使用神行术,花费10点原力(所以有限制
3.普通跑步
这样其实dp方程很明显,在这三种转移中取max值,但是同时要维护一个原力储量的变量,用来表示是否能够使用神行术
但是若是将三个情况统一处理,显然是不好办的,我们知道的是,若是,不回复原力,那么我们往后都断断无法使用神行,若是将三种情况一起取最优
那么决策就会出现原力用完无法神行,贪心不断取跑步而不能恢复原力而无法再用神行
因此我们必须要分开处理
我们可以把神行和跑步分开处理,因为神行的使用需要原力,我们将恢复原力与神行一起处理
原力够10点就神行,不够就恢复原力
最后在分别在每一秒处理是否跑步

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 300086;
 4 int m, s, t;
 5 int f[maxn];
 6 
 7 inline int read() {
 8     int x = 0, y = 1;
 9     char ch = getchar();
10     while(!isdigit(ch)) {
11         if(ch == '-') y = -1;
12         ch = getchar();
13     }
14     while(isdigit(ch)) {
15         x = (x << 1) + (x << 3) + ch - '0';
16         ch = getchar();
17     }
18     return x * y;
19 }
20 
21 int main() {
22     m = read(), s = read(), t = read();
23     for(int i = 1; i <= t; ++i) {
24         if(m >= 10) f[i] = f[i - 1] + 60, m -= 10;
25         else m += 4, f[i] = f[i - 1];
26     }
27     for(int i = 1; i <= t; ++i) {
28         f[i] = max(f[i], f[i - 1] + 17);
29         if(f[i] >= s) {
30             cout << "Yes" << '\n' << i << '\n';
31             return 0;
32         }
33     }
34     cout << "No" << '\n' << f[t] << '\n';
35     return 0;
36 }

猜你喜欢

转载自www.cnblogs.com/ywjblog/p/9384393.html