NOIP2014 飛揚的小鳥
Problem
https://www.luogu.org/problemnew/show/P1941
Solution
30pts
\(5 \leq n,m \leq 10, k = 0\)
DFS(i,j,k)
表示橫坐標為 \(i\),高度為 \(j\),走了 \(k\) 步
暴力 DFS 即可,只要始終保持 \(j > 0\), 時間復雜度 \(O(4^nm)\)
50pts/70pts
\(5 \leq n \leq 20, 5 \leq m \leq 10\)
如果仍然暴力 DFS,時間復雜度無法承受。
這個問題具有明顯的 最優子結構 和 重疊子問題 的特征,可以考慮動態規劃或者記憶化搜索;
狀態:\(f[i][j]\)
轉移:\(f[i][j] = Min\{ f[i-1][j+y[i-1]], f[i-1][j-kx[i-1]]+k \}\)
需要註意的是,\(f[i][m]\) 需要特殊的轉移:\(f[i][m] = Min\{f[i-1][k] + \lceil \frac{m-k}{x[i-1]} \rceil \} (k \not= m),Min\{f[i-1][m] + 1\}\)。
這是一個 \(2D/1D\) 動態規劃,時間復雜度 \(O(nm^2)\).
由於有特殊性質,50pts 的動態規劃時間復雜度是 \(O(nm)\)
100pts
有大佬告訴我這個 DP 式子很像完全背包,所以可以用完全背包的方法優化;
這個方法以後再補,先來講講我的方法:
優化的動機主要是 重復 和 不必要 ,觀察上面那個 DP 式子,可以發現 \(f[i][j]\) 和 \(f[i][j-x[i-1]]\) 的轉移有大量重復,我們展開轉移式子的第 2 項,可以得到:
\[
f[i][j] <= (Min)f[i-1][j-x[i-1]] + 1 \f[i-1][j-2x[i-1]] + 2 \f[i-1][j-3x[i-1]] + 3 \\cdots \f[i-1][j-kx[i-1]] + k \\f[i][j-x[i-1]] <= (Min)f[i-1][j-2x[i-1]] + 1\f[i-1][j-3x[i-1]] + 2 \f[i-1][j-4x[i-1]] + 3 \\cdots \f[i-1][j-kx[i-1]] + k-1 \\]
可以看到,\(f[i][j]\) 的轉移和 \(f[i][j-x[i-1]]\) 的轉移第 \(2\) 項就相差了 \(1\) 項,其它轉移都加了 \(1\),這對最小值是沒有影響的。
那麽不妨用 \(g[i][j]\) 表示 \(Min\{f[i-1][j-kx[i-1]]+k\}\),就可以得到新的轉移:
\[
g[i][j] = min\{f[i-1][j-x[i-1]]+1, g[i][j-x[i-1]]+1\} \f[i][j] = min\{f[i-1][j+y[i-1]], g[i][j]\}
\]
這樣就可以在 \(O(nm)\) 的時間內完成 DP 了。
NOIP2014 飛揚的小鳥