75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
19 01 23 75 03 34
88 02 77 73 07 63 67
99 65 04 28 06 16 70 92
41 41 26 56 83 40 80 70 33
41 48 72 33 47 32 37 16 94 29
53 71 44 65 25 43 91 52 97 51 14
70 11 33 28 77 73 17 78 39 68 17 57
91 71 52 38 17 14 91 43 58 50 27 29 48
63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23
上手就想贪心算法求解,但明显不行,这里应该用动态规划
#include<iostream>
using namespace std;
int ans, num[20][20], dp[20][20];
int main() {
for (int i = 1; i <= 15; i++) {
for (int j = 1; j <= i; j++) {
cin >> num[i][j];
}
}
for (int i = 1; i <= 15; i++) {
for (int j = 1; j <= i; j++) {
dp[i][j] = max(dp[i-1][j], dp[i - 1][j - 1]) + num[i][j];
ans = max(ans, dp[i][j]);
}
}
cout << ans << endl;
return 0;
}
为什么是在本位置上层的j和j-1去选而不是j和j+1呢?原因是放在三角形中,与num[3][2]相邻的上一层是num[2][1]与num[2][2],也就是说num[i][j]夹在num[i-1][j-1]与num[i-1][j]直接,根本与num[i-1][j+1]不相邻
跟着代码走一遍发现他是从第一层走到最后一层的,可能和想象中的动态规划不一致,我们把代码稍作修改,使其从最后一层加到第一层
#include<iostream>
using namespace std;
int ans, num[20][20], dp[20][20];
int main() {
for (int i = 1; i <= 15; i++) {
for (int j = 1; j <= i; j++) {
cin >> num[i][j];
}
}
for (int i = 15; i >= 1; i--) {
for (int j = 1; j <= i; j++) {
dp[i][j] = max(dp[i+1][j], dp[i +1][j +1]) + num[i][j];
ans = max(ans, dp[i][j]);
}
}
cout << ans << endl;
return 0;
}
这样子看就能看出这个动态规划的本质了,就是从最后一层往上层加,但是这还是把全部都加了一遍,
应该可以采用递归方式,不将结果存储到表里面更快地得出结果;