数字三角形经典 DP:自底向上滚动数组,O(h²) 时间求最大路径和。
OJ: roj
题目 ID: 1288
难度:入门
标签:动态规划数字三角形滚动数组
创建: 2026-09-30 03:26
更新: 2026-10-05 08:09
题目描述
给定一个高度为 5,7,3 8,8 1 0,2 7 4 4,4 5 2 6 5 时输出 30。
思路
设
参考代码
Python 版:
python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-30 03:27
# update_at: 2026-10-04 10:27
import sys
def solve() -> None:
data = iter(map(int, sys.stdin.buffer.read().split()))
n = next(data) # 三角形高度,也是最底层一行里的数字个数
tri: list[list[int]] = []
for i in range(1, n + 1):
tri.append([next(data) for _ in range(i)]) # 第 i 行共 i 个数
dp = tri[-1][:] # 最底层 dp 初值
for r in range(n - 2, -1, -1):
dp = [tri[r][j] + max(dp[j], dp[j + 1]) for j in range(r + 1)]
print(dp[0])
if __name__ == "__main__":
solve()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-05 08:09
* update_at: 2026-10-05 08:09
*/
// 数字三角形:自底向上 DP,dp[j] 表示从当前行第 j 列出发到底部的最大路径和。
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXH = 105; // h <= 100
int h; // 三角形高度
ll tri[MAXH][MAXH]; // tri[r][j] 表示第 r 行第 j 列的数字(下标从 1 开始)
ll dp[MAXH]; // 滚动数组:dp[j] = 从当前行第 j 列出发到底部的最大路径和
int main() {
scanf("%d", &h);
for (int i = 1; i <= h; i++)
for (int j = 1; j <= i; j++)
scanf("%lld", &tri[i][j]);
// 初始化为最底层一行:从底层出发的最大和就是自身
for (int j = 1; j <= h; j++) dp[j] = tri[h][j];
// 自底向上递推:f(r,j) = a(r,j) + max(f(r+1,j), f(r+1,j+1))
for (int i = h - 1; i >= 1; i--)
for (int j = 1; j <= i; j++)
dp[j] = tri[i][j] + max(dp[j], dp[j + 1]);
printf("%lld\n", dp[1]);
return 0;
}