数字三角形 (DP || 爆搜)

该博客讨论了一种数字三角形问题,其中任务是找到从顶部到底部的最大路径和。作者提到了两种方法,一种是深度优先搜索(DFS),但可能会导致超时,另一种是动态规划解决方案,它更有效。动态规划方法通过维护一个二维数组`dp`来存储到达每个位置的最大路径和,并根据题目要求更新转移方程。最后,根据奇偶性判断输出最大路径和。
摘要由CSDN通过智能技术生成

文章目录

数字三角形

题目描述
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。
路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右 边的那个数。此外,向左下走的次数与向右下走的次数相差不能超过 1。
输入描述
输入的第一行包含一个整数 N(1≤N≤100),表示三角形的行数。
下面的 N 行给出数字三角形。数字三角形上的数都是 0 至 100 之间的整数。
输出描述
输出一个整数,表示答案。
用例输入 1

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

用例输出 1

27

思路

从上往下模拟,当前这一层 坐标(x,y), 能走到下一层的 (x + 1,y - 1) 和(x + 1,y + 1),关于题目要求只需要记录往左和往右的步数,到达最后一层在判断即可
方法一 :dfs思想会超时

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 110;

int n;
int maxnum;
int note[maxn] = { 0 }, left1 = 0, right1 = 0, pos = 1;
int a[maxn][maxn];

void dfs(int x, int left, int right) {

    if (x == n) { // 递归边界
        if (abs(left - right) > 1) return;

        note[x] = a[x][1 + right]; //
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            sum += note[i];
        }
        if (sum > maxnum) maxnum = sum; // 刷新最大值
        return;
    }

    note[x] = a[x][1 + right]; // 记录第x层的数字
    dfs(x + 1, left + 1, right);
    dfs(x + 1, left, right + 1);
}


int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= i; j++) {
            cin >> a[i][j];
        }
    }

    dfs(1,0,0); //

    cout << maxnum << endl;

    getchar();
    getchar();
    return 0;
}
  

方法二: 动态规划
思路:dp [i] [j] 代表前 i 层,第 j个位置所能到达的最大值,如果选择(i , j)
这个位置,说明就是上一层能到达这个位置的最大值,那么就是(i - 1,j),(i -
1,j - 1) ,但是题目还有要求往左和往右的步数差不超过一,其实这个就是走
到最后一层的中间,奇数就是中间的数,偶数就是中间两个数的最大值
动态转移方程: dp [i] [j] = max(dp [i - 1] [j] , dp [i - 1] [j - 1])

#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
int a[105][105];
int n;
int dp[105][105];
int main(){
	cin >> n ;
	for(int i = 1 ; i <= n ; i++){
		for(int j = 1 ; j <= i ; j++){
			cin >> a[i][j];
		}
	}
	for(int i = 1 ; i <= n ; i++){
		for(int j = 1 ; j <= i ; j++){
			dp[i][j] = max(dp[i - 1][j] ,dp[i - 1][j - 1])+ a[i][j];
		}
	}
	if(n % 2 == 0) cout << max(dp[n][n / 2],dp[n][n / 2 +1]) << endl;
	else cout << dp[n][n / 2 + 1];
	return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值