自殺遊戲【牛客小白月賽7 B】【DP動態規劃】【詳解、對於WA細節上的分析】
阿新 • • 發佈:2018-12-10
題目連結
思路:
細節的處理尤為重要,後面會提點一下。
這道題,我的想法是從0這個必死局開始往後找最優解下Alice或者Bob的生死,初始化dp[]是全Bob活,也就是Alice死,dp【i】是指以最優解往下走,到達i時刻死的人到底會是誰,然後從1號節點開始遍歷,由於a、b很小,所以這道題我的O(t*(b-a))的時間複雜度還是可行的。
我遍歷到點i,然後找它前面的時間線【i-b-1,i-a-1】(後面簡稱之為區間K),這麼尋覓也是有原因的,若是區間K存在這樣的點是Bob活,而在此情況,一定是Alice要找生存的機會,所以得反轉,那麼dp[i]時刻就是true(Alice找到生的機會),反之就無須,畢竟初始化就是全都是Bob贏的。
細節:
我在細節處WA了好幾發了,所以得寫下來,避免同樣犯錯的讀者。
-
如果dp[i-1]是Alice死,那麼到了i時刻,就意味著有一次交換,而交換是需要1s時間的,故生死轉換。
-
遍歷得從1~T且一定是1開始,因為0時刻反正是直接爆的。
-
訪問前面的節點生死關係時,一定要注意時間得>=0,不然就不存在這樣的時間。
完整程式碼:
#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 using namespace std; typedef long long ll; const int maxN=1e5+5; int T, a, b; bool dp[maxN]; //如果i時刻為true就是Alice活,否則Bob活 int main() { while(scanf("%d%d%d",&T, &a, &b)!=EOF) //一共有T時間緩衝爆炸 { memset(dp, false, sizeof(dp)); for(int i=1; i<=T; i++) //i指的是到目前狀態時候,誰會死,從1開始,因為0是必死局 { if(!dp[i-1]) dp[i]=true; for(int j=i-b-1; j<=i-a-1; j++) { if(j>=0 && !dp[j]) //若是j時刻是Bob死,那麼這次尋取最優解就是Alice活 { dp[i]=true; break; } } } printf(dp[T]?"Alice\n":"Bob\n"); } return 0; }