【題解】Luogu P2690 接蘋果
阿新 • • 發佈:2018-12-12
這道題以時間為階段,是一道很明顯的線性dp。
這道題有一個要點: 因為只有兩棵樹且初始為第一棵樹下,所以移動奇數次到達第二顆樹,移動偶數次則到達第一棵樹。
理解這個時候就可以直接推出狀態轉移方程了。
具體可以看下面的程式碼來理解。
#include <iostream> #define MAX_N 31 using namespace std; int t, n; int dp[MAX_N]; // 移動了i次後的蘋果最優方案,這裡運用了滾動陣列 int ans; int main() { cin >> t >> n; int v; for(register int i = 1; i <= t; ++i) // 第i分鐘 { cin >> v; for(register int j = min(i, n) - ((v & 1) == (min(i, n) & 1)); j >= 0; j -= 2) // 第j次移動時到達當前這棵樹v // min(i, n):因為當i < n時,最多隻有i次移動,所以就這麼求最小值 // & 1可以理解為 % 2 // 如果當前樹的編號的奇偶性與最多移動次數n的奇偶性相同,就最多隻能移動(n - 1)次從而回到當前這棵樹,具體可以自己帶入資料驗證 // j -= 2: 因為要再移動2次才能回到當前的樹,所以就- 2 { if(j) dp[j] = max(dp[j], dp[j - 1]) + 1; // 如果j不為0,那麼就可以從原地不動和從第j-1次移動到另一棵樹後在移動回這一棵樹中的最優方案 else ++dp[j]; // 如果j為0,那麼就代表無法移動,所以就只能在最開始的第一棵樹撿蘋果(j = 0時v就為1)。 } } for(register int i = 0; i <= n; ++i) { ans = max(ans, dp[i]); } cout << ans; return 0; }