dp-數字三角形
阿新 • • 發佈:2021-06-12
數字三角形問題是一個很經典的dp
問題,因為這個題是在書上看到的,所以根本不知道輸入是什麼!只能通過經驗判斷輸入!!!!
注意:當前版本是我自己臆想出來的輸入。
題目描述
有一個非負整數組成的三角形,第一行只有一個數,除了最下行之外每個數的左下方和右下方各有一個數,從第一行的數開始每次可以往左下或者右下走一格,直到走到最下行,把沿途經過的數全部加起來,如何走才能得到最大和?
思考過程1
像題目中這樣說,不就是轉換成一個數組麼?
如圖所示,先轉成陣列:
注意:第\(0\)行和第\(0\)列是不需要的,因為不好計算。第\(k\)行有\(k\)個數。
像這種結構找最大或者最小值,一般就是用深搜,每條路徑都要遍歷一遍。確定了深搜之後,想一下輸入的問題,我以為這道題的輸入是給定\(n\)
左邊就是個等差數列,結果為:
\[\frac{(1+k)*k}{2} \]展開可得:
\[k^2+k-2n \geq 0 \]這裡求解\(k\),根據韋達定理,可知:
\[x=\frac{-b\pm \sqrt{b^2-4ac}}{2a} \]同過這個公式可以求得\(k\):
\[k_1\geq\frac{\sqrt{1+8n}-1}{2} \\ k_2\leq\frac{-1 - \sqrt{1+8n}}{2} \]因為\(k_2\)
ceil()
。
深搜程式碼
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <vector> #include <map> #include <cmath> #include <deque> using namespace std; #define MAX_N 100 #define print(a) { \ for (int i = 0; i < 10; i++) {\ for (int j = 0; j < 10; j++) {\ cout << grid[i][j] << " ";\ }\ cout << endl;\ }\ } int n, grid[MAX_N + 5][MAX_N + 5], ans = 0; int k; void dfs(int x, int y, int sum) { sum += grid[x][y]; // cout << "(" << x << ", " << y << ")" << " " << sum << endl; if (x == k) { ans = max(sum, ans); return ; } if (grid[x + 1][y] >= 0) { dfs(x + 1, y, sum); } if (grid[x + 1][y + 1] >= 0) { dfs(x + 1, y + 1, sum); } } void solve() { memset(grid, -1, sizeof(grid)); cin >> n; k = ceil((sqrt(1 + 8 * n) - 1) / 2); cout << "k = " << k << endl; for (int i = 1; i <= k; i++) { for (int j = 1; j <= i; j++) { cin >> grid[i][j]; // print(grid); } } dfs(1, 1, 0); cout << ans << endl; } int main() { solve(); return 0; }
未完!等回來再寫!