洛谷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 }