動態規劃-數字三角形
阿新 • • 發佈:2019-02-16
描述:
數字三角形,從三角形頂部往下走,只能往左下或右下走,求走到最下面時所經過的數字和最大為多少?(下圖為n=6時的情況)
2 | |||||
96 | 30 | ||||
83 | 52 | 60 | |||
21 | 65 | 44 | 61 | ||
8 | 79 | 50 | 41 | 21 | |
61 | 41 | 50 | 38 | 79 | 10 |
第1行:整數n(1<=n<=1000)
第2-n+1行:每行若干整數,第i行有i-1個整數,空格分隔。
輸出:
經過的最大數字之和
示例測試集:
- 第1組
輸入:
3
1
7 2
1 0 10
輸出:
13
最差演算法——遍歷
#include<iostream> using namespace std; int tem_rsl(int now,int now_l,int now_r) { if (now + now_l > now + now_r) return now + now_l; else return now + now_r; } int main() { int n;//輸入數字的行數 1-1000 cin >> n; int tot_n = (1 + n)*n / 2; int* a = new int[tot_n+1]; for (int i = 1; i < tot_n + 1; i++) { cin >> a[i]; } int layer = n; int temp = n - 1; for (int i = tot_n-n; i > 0; i--) { a[i] = tem_rsl(a[i], a[i + layer], a[i + layer + 1]); temp--; if (temp == 0) { layer--; temp = layer-1; } } cout << a[1] << endl; return 0; }
一次改進——遞迴解法
#include<iostream> #define MAX 1000 using namespace std; int n; int a[MAX][MAX]; int findmax(int i,int j) { if (i == n) { return a[i][j]; } else { int x = a[i][j] + findmax(i + 1, j + 1); int y = a[i][j] + findmax(i + 1, j); return x > y ? x : y; } } int main() { //輸入數字的行數 1-1000 cin >> n; for (int i = 1; i <= n; i++) { for (int j = 1; j <= i; j++) { cin >> a[i][j]; } } cout << findmax(1, 1) << endl; return 0; }
再改進——記憶遞迴動歸程式
改進遞迴解法中,中間部分重複解法的情況。
#include<iostream> #define MAX 1000 using namespace std; int n; int a[MAX][MAX]; int sum_max[MAX][MAX]; int findmax(int i,int j) { if (sum_max[i][j]!=-1) { return sum_max[i][j]; } else if (i == n) { sum_max[i][j] = a[i][j]; return sum_max[i][j]; } else { int x = a[i][j] + findmax(i + 1, j + 1); int y = a[i][j] + findmax(i + 1, j); if (x > y) { sum_max[i][j] = x; } else { sum_max[i][j] = y; } return sum_max[i][j]; } } int main() { //輸入數字的行數 1-1000 cin >> n; for (int i = 1; i <= n; i++) { for (int j = 1; j <= i; j++) { cin >> a[i][j]; sum_max[i][j] = -1; } } cout << findmax(1, 1) << endl; return 0; }
特別注意點:
寫遞迴解法的步驟:1 不要考慮之後如何查詢,只需要寫好當前查詢的辦法。
2 一定要寫上觸底返回的情況。