杭电OJ 2084 数塔
数塔
题目明确告诉你,这是一道DP动态规划问题,那么首先先回顾什么是动态规划,就是把原问题分解为多个子问题,再记忆子问题的结果,来降低时间复杂度。
观察这个数塔,首先设置一个数组dp[][],令
-
1.边界情况,结点
或者结点 ,此时只有不断向上一条路; -
2.当结点i属于当前层次的中间的结点位置,那么
;
得到状态转移方程之后,我们只需遍历求出以最后一层的每个结点为终点的最大值,然后输出其中的最大值即可。
AC代码如下:
//2024-03-28 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 100 + 2; int arr[MAXN][MAXN]; int dp[MAXN][MAXN]; //第j层的第i个结点为终点的最大和 递归+记忆化 int Function(int i, int j) { if(dp[j][i] != -1) { return dp[j][i]; } int answer; if(i == 0 && j == 0) {//递归出口 answer = arr[j][i]; } else{ answer = arr[j][i] + max(Function(i-1, j-1), Function(i, j-1)); } dp[j][i] = answer; return answer; } int main() { int c, n; cin >> c; while(c--) { cin >> n; for(int i = 0; i < n; ++i) { for(int j = 0; j <= i; ++j) { cin >> arr[i][j]; } } memset(dp, 0, sizeof(dp)); for(int j = 1; j < n; ++j) { //j层i个结点 for(int i = 1; i < j; ++i) { dp[j][i] = -1; } } for(int j = 0; j < n; ++j) { //边界情况 for(int k = 0; k <= j; ++k) { dp[j][0] += arr[k][0]; if(j != 0) dp[j][j] += arr[k][k]; } } int maximum = -INT_MAX; for(int i = 0; i < n; ++i) { maximum = max(maximum, Function(i, n-1)); } cout << maximum << endl; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)