数塔

问题

描述

从数塔的顶层出发,寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或右下走。只需要求出这个最大和即可,不必给出具体路径。
三角形的行数为1-100,数字为0-99。

输入格式:

输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。

输出格式:

对于每个测试实例,输出可能得到的最大和,每个实例的输出占一行。

样例输入:

1
5
8
12 15
3 9 6
8 10 5 12
16 4 18 10 9

样例输出:

60

思路

这是一个基础的DP问题,要想知道第一个结点往下走的时候是往左走还是往右走,就要判断是从左结点走经过的结点数字总数较大还是往右结点走经过的结点数字总数较大,而对于左结点,是往左结点走经过的结点数字总数较大还是往右结点走经过的结点数
字总数较大,对于左结点的左结点…你懂的,这个时候就开始循环了。
就这样一直循环到倒数第二层,对于这个结点,是往左节点走好还是往右节点走好,那好办啊,直接比较这个结点的左孩子大还是又孩子大不就结了,把大的孩子数字直接加到这个节点上就得到经过这个结点的最大结点数字总数了,哈哈,这样就好办了,我
们就可以逐层求上面的各个节点的最大结点总数了,一直到第一层A[1][1]的值就是经过的结点的数字之和最大是多少。
存储这个数塔我们使用二位数组,而对于任意一个结点,左孩子是dp[i+1][j]或者dp[i+1][j+1],这是我们就要判断它的经过它左孩子得到的最大结点数更大还是右孩子经过的最大结点数更大一点。必须从倒数第二层到第一层逐层判断,这样才能保证孩子
中存储的是经过它的最大结点数总数,而不是它自己的结点数。
数组的一层更新完这层存储的数字就是经过该结点的最大结点总数。

code

代码君
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
#define Elaina 0
const int N=10050;
ll m,n,f[N][N];
int main(){
	cin>>m; 
	while(m--){
		cin>>n;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=i;j++){
				cin>>f[i][j];
			}
		}
		for(int i=n-1;i>0;i--){
			for(int j=1;j<=i;j++){
				f[i][j]+=max(f[i+1][j],f[i+1][j+1]);
			}
		}
		cout<<f[1][1]<<endl;
	}
	return Elaina;
}
posted @ 2024-02-16 16:42  Elaina_0  阅读(46)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end