https://www.luogu.com.cn/problem/P1095
状态dp[i]表示i时刻只用魔法的最远距离。
对于跑步,只需要利用处理好的dp维护一下。
其正确性基于贪心策略,长远的考虑,一定是用魔法的距离比跑步好,但是在个别情况,休息的过程时就有可能不如跑步,因此加入跑步来动态维护,如果大于s了就及时退出。
容易知道有跑步参与答案一定是只参与最后一次跑步的。需要一点数学/物理直觉。
#pragma warning(disable:4996) #include<iostream> #include<algorithm> #include<bitset> #include<tuple> #include<unordered_map> #include<fstream> #include<iomanip> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<list> #include<queue> #include<stack> #include<sstream> #include<cstdio> #include<ctime> #include<cstdlib> #define pb push_back #define INF 0x3f3f3f3f #define inf 0x7FFFFFFF #define moD 1000000003 #define pii pair<ll,ll> #define eps 1e-8 #define equals(a,b) (fabs(a-b)<eps) #define bug puts("bug") #define re register #define fi first #define se second typedef long long ll; typedef unsigned long long ull; const ll MOD = 1e9 + 7; const int maxn = 3e5 +5; const double Inf = 10000.0; const double PI = acos(-1.0); using namespace std; int dp[maxn]; int main() { int n, m, t; scanf("%d%d%d", &m, &n, &t); for (int i = 1; i <= t; i++) if (m >= 10) dp[i] = dp[i - 1] + 60, m -= 10; else dp[i] = dp[i - 1], m += 4; for (int i = 1; i <= t; i++) { dp[i] = max(dp[i], dp[i - 1] + 17); if (dp[i] >= n) { puts("Yes"); printf("%d", i); return 0; } } puts("No"); printf("%d", dp[t]); }