问题描述
状态转移方程
代码实现
- 方法1:效率低下
#include<iostream>
#include<string.h>
#define maxn 1000 + 5
using namespace std;
int a[maxn][maxn];
int d[maxn][maxn];
int n;
int D (int i, int j) {
return a[i][j] + (i == n ? 0 : max(D(i+1, j), D(i+1, j+1)));
}
int main() {
int i, j;
for (; cin >> n && n;) {
memset(d, 0, sizeof(d));
for (i = 1; i <= n; i++) { //控制有多少层
for (j = 1; j <= i; j++) {
cin >> a[i][j];
}
}
for (i = 1; i <= n; i++) {
for (j = 1; j <= i; j++) {
d[i][j] = D(i, j);
}
}
cout << d[1][1]; //注意最终结果的存储位置
}
}
原因:
方法2: 倒过来,从树的底层开始思考:
- 方法3: 对于 方法1 进行改进,将已经计算过的 d[i][j] 进行保存:
#include<iostream>
#include<string.h>
#define maxn 1000 + 5
using namespace std;
int a[maxn][maxn];
int d[maxn][maxn];
int n;
int D (int i, int j) {
if (d[i][j] > 0) return d[i][j] ; //在这里做了优化
return d[i][j] = a[i][j] + (i == n ? 0 : max(D(i+1, j), D(i+1, j+1))); //在这里对计算过的分支进行保存
}
int main() {
int i, j;
for (; cin >> n && n;) {
memset(d, -1, sizeof(d)); //注意这里初始化为-1,很关键
for (i = 1; i <= n; i++) { //控制有多少层
for (j = 1; j <= i; j++) {
cin >> a[i][j];
}
}
for (j = 1; j <= n; j++) {
d[n][j] = a[n][j];
}
for(i = n-1; i >= 1; i--) {
for (j = 1; j <= i; j++) {
d[i][j] = a[i][j] + max(d[i+1][j], d[i+1][j+1]);
}
}
cout << d[1][1];
}
}