1. 程式人生 > >NOIP2014 飛揚的小鳥

NOIP2014 飛揚的小鳥

問題 不必要 n) inline 動態 轉移 math problem 時間復雜度

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]\)

表示橫坐標為 \(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 飛揚的小鳥