数塔取数
这是一道入门的动态规划题, 没做过的可能很难想出, 但是做过的会觉得很简单.
这道题相比最基础的数塔取数多了一个求路径. 只要记录所继承的下一层数的下标. 最后从头开始走过这些下标就是路径了.
时间复杂度是O(n), n为数塔的数的个数.
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 1005;
int n, sum[maxn][maxn];
struct T {
int x, y;
} arr[maxn][maxn];
int main()
{
memset(sum, 0, sizeof(sum));
cin >> n;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= i; ++j) {
cin >> arr[i][j].x;
}
}
for (int i = 1; i <= n; ++i) {
arr[n][i].y = i;
sum[n][i] = arr[n][i].x;
}
for (int i = n - 1; i >= 1; --i) {
for (int j = 1; j <= i; ++j) {
if (sum[i + 1][j] > sum[i + 1][j + 1]) {
sum[i][j] = sum[i + 1][j] + arr[i][j].x;
arr[i][j].y = j;
} else {
sum[i][j] = sum[i + 1][j + 1] + arr[i][j].x;
arr[i][j].y = j + 1;
}
}
}
/*for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= i; ++j) {
cout << sum[i][j] << ' ';
}
cout << endl;
}*/
cout << sum[1][1] << '\n';
int k = 1, next = 1;
while (k <= n) {
cout << arr[k][next].x << ' ';
next = arr[k++][next].y;
}
cout << endl;
}
/*
5
9
12 15
10 6 8
2 18 9 5
19 7 10 4 16
*/