惡魔獵手尤迪安野心勃勃,他背叛了暗夜精靈,率領深藏在海底的娜迦族企圖叛變。守望者在與尤迪安的交鋒中遭遇了圍殺,被困在一個荒蕪的大島上。爲了殺死守望者,尤迪安開始對這個荒島施咒,這座島很快就會沉下去。到那時,島上的所有人都會遇難。守望者的跑步速度爲17m/s,以這樣的速度是無法逃離荒島的。慶幸的是守望者擁有閃爍法術,可在1s內移動60m,不過每次使用閃爍法術都會消耗魔法值10點。守望者的魔法值恢復的速度爲4點/s,只有處在原地休息狀態時才能恢復。現在已知守望者的魔法初值M,他所在的初始位置與島的出口之間的距離S,島沉沒的時間T。你的任務是寫一個程序幫助守望者計算如何在最短的時間內逃離荒島,若不能逃出,則輸出守望者在剩下的時間內能走的最遠距離。注意:守望者跑步、閃爍或休息活動均以秒(s)爲單位,且每次活動的持續時間爲整數秒。距離的單位爲米(m)。
輸入格式
共一行,包括空格隔開的三個非負整數M,S,T。
輸出格式
共兩行。
第1行爲字符串“Yes”或“No”(區分大小寫),即守望者是否能逃離荒島。
第2行包含一個整數。第一行爲“Yes”(區分大小寫)時表示守望者逃離荒島的最短時間;第一行爲“No”(區分大小寫)時表示守望者能走的最遠距離。
#輸入1
39 200 4
輸出
No
197
#輸入2
36 255 10
輸出
Yes
6
我感覺cin比scanf好寫,但是cin慢;學了一個加速函數 ios::sync_with_stdio(false) 寫在main函數開頭即可
int dp[300005];表示前i分鐘內能跑多長的距離
100%的數據 1 <= T <= 300000, 0 <= M <=1000, 1 <= S <=1e8.
#include <iostream>
#include <cstdio>
using namespace std;
int dp[300005];
int main()
{
ios::sync_with_stdio(false);
int M, S, T;
cin >> M >> S >> T;
for(int i = 1; i <= T; i++) // 我們先來看看從頭到尾閃爍可以走多少
{
if(M >= 10) // 魔法值夠閃爍
{
M -= 10; // 閃爍消耗魔法值
dp[i] = dp[i-1]+60; // 這一秒閃爍
}
else // 魔法值不夠閃爍,蓄力
{
M += 4;
dp[i] = dp[i-1]; // 蓄力時,不能行動
}
}
for(int i = 1; i <= T; i++) // 從頭到尾跑步,獲取最優解
{
dp[i] = max(dp[i], dp[i-1]+17); // 獲取最優解
if(dp[i] >= S)
{
cout << "Yes" << endl << i;
return 0;
}
}
cout << "No" << endl << dp[T];
return 0;
}
還有一種方法
分別儲存兩種方式所走的路程, 在途中選取最優的, 還是DP的思想
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int M, S, T;
cin >> M >> S >> T;
int s1, s2;
for(int i = 1; i <= T; i++)
{
if(M >= 10)
{
s1 += 60;
M -= 10;
}
else M += 4;
s2 += 17;
if(s1 >= s2) s2 = s1;
if(s2 >= S)
{
cout << "Yes" << endl << i;
return 0;
}
}
cout << "No" << endl << s2;
return 0;
}