y式dp-集合角度
集合劃分
\((i,j)一定是從(i-1,j),(i,j-1)兩步中轉移而來\)
轉移方程**
時間複雜度\(o(n^2)\)
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
f[i][j] = max(f[i-1][j],f[i][j-1]) + w[i][j];
優化
從轉移方程來看,我們每次只用到了本層和上一層的資料,因此我們可以採用滾動陣列來進行空間上的優化
f[2][n], w[2][n];
for (int i = 1; i <=n; ++i)
for (int j = 1; j <= n; ++j)
cout 《本題相比與摘花生題目多了乙個限制條件,要求在\(2n-1\)的時間內達到\((n,m)\),結合曼哈頓距離可以得知,要求每一步都是能夠減小曼哈頓距離的,達到最短路的乙個效果,那每一步的選擇必定是朝右或者朝下行走,即滿足摘花生模型。
曼哈頓距離:兩個點在座標軸上的絕對值,即\(d = |x1-x2|+|y1-y2|\)
dp
集合劃分
以最後一步劃分, \((i,j)一定是從(i-1,j),(i,j-1)兩步中轉移而來\)
code
本題不同的地方在於dp的初始化和邊界問題,需要特判\((1,1)\),同時因為是取最小值,所以需要初始化為\(inf\)。
memset(f, 0x3f, sizeof f); //初始化
f[1][1] = w[1][1];
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
f[i][j] = min();
區別
走兩次,並取兩次所取數之和的最大值。
錯誤思路
乙個貪心的想法是走兩次,每次都是依據當前情況來取最優解,兩個最優解相加就是答案,但其實是不行的,第二次dp的結果其實是在第一次dp產生後續影響的前提下完成的乙個區域性最優,不滿足無後效性,所以兩次區域性最優無法推出整體最優解,得到的是乙個最優解的近似值。
正確思路
同時走,從\((1,1),(1,1)\)走到\((n,n),(n,n)\),那麼兩次dp得到的結果都是根據當前地圖得到的答案,且衝突的點——重複經過的點可以被解決。
dp狀態計算(四個狀態取max)
相關狀態解釋
code
for (int k = 2; k <= n; ++k)
for (int i1 = 1; i1 <= n; ++i1)
for (int i2 = 1; i2 <= n; ++i2 )
數字三角形
題目描述 示出了乙個數字三角形。請編乙個程式計算從頂至底的某處的一條路 徑,使該路徑所經過的數字的總和最大。每一步可沿左斜線向下或右斜線向下走 1 三角形行數 25 三角形中的數字為整數 1000 輸入第一行為n,表示有n行 後面n行表示三角形每條路的路徑權 輸出路徑所經過的數字的總和最大的答案 樣...
數字三角形
description 有如下所示的數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?input 輸入資料首先包括乙個整數c,表示測試例項的個數,每個測試例項的第一行是乙個整數n 1 n 100 表示數塔的高度,接下來用n行數字表示數塔,其中第i行有個i個整數,...
數字三角形
3 8 8 1 0 2 7 4 4 4 5 2 6 5 上圖給出了乙個數字三角形。從三角形的頂部到底部有很多條不同的路徑。對於每條路徑,把路徑上面的數加起來可以得到乙個和,和最大的路徑稱為最佳路徑。你的任務就是求出最佳路徑上的數字之和。input 1 5 7 3 8 8 1 0 2 7 4 4 4 ...