c语言动态规划解决数字三角形

 数字三角形就是用户输入行数n,输入一个三角形,要求计算出第一行到最后一行的最大路径和。

看这个题初学小白一开始真的有点难想,后来看了很久的动态规划课程才明白过来,一定要学会画图来思考!

比如要算下面一个三角形的最大路径和,n=5

7
38
810
2744
45265

直接从第一行算,然后分析只能走下面一行的正下方或者是右下边,采用递归的话就会很麻烦并且会超时,数值过大的话。

所以要从最后一行开始计算哦,最后一行到底部的路径就是他们自己的数值,所以这个就是初始化条件,也就是边界值哦,然后再看倒数第二行,依次往上计算(就是倒数第二行就是第二行自己的数加上最后一行的两个数中的较大值相加)。要定义一个二维数组来存放最大总和路径maxSum[MAX][MAX],用另外一个二维数组存放数字三角形的值D[MAX][MAX]。

1.先读入三角形的数值到D[i][j]

2.进行最后一行的初始化,即maxSum[n][i]=D[n][i].

3.根据动态方程maxSum[i][j]=max(maxSum[i+1][j],maxSum[i+1][j+1])+D[i][j]递归计算

#include<iostream>
#include<algorithm>
using namespace std; 
const int MAX=101;
int D[MAX][MAX];
int  maxSum[MAX][MAX];
/*
样例运行
5
7
3 8
8 1 0
2 7 4 4 
4 5 2 6 5
结果是30 
*/
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			cin>>D[i][j];//输入每一行数字三角形的每一个数值 
		}
	}
	for(int i=1;i<=n;i++)//最后一行初始化 
	{
		maxSum[n][i]=D[n][i];
	}
	for(int i=n-1;i>=1;i--)//注意是从底部往上递推 ,而且是倒数第二行 
	{
		for(int j=1;j<=i;j++)
		{
			maxSum[i][j]=max(maxSum[i+1][j],maxSum[i+1][j+1])+D[i][j];
		}
	 } 
	 cout<<maxSum[1][1]<<endl;
	
	return 0;
}

小小优化版本

为什么会有优化的版本因为用表格看的话,其实只需要最后一行的数值就可以哦,把maxSum定义为一维数组即可,滚动数组求解更优化空间结构,但是时间复杂度不变的哦

#include<iostream>
#include<algorithm>
using namespace std; 
const int MAX=101;
int D[MAX][MAX];
int  maxSum[MAX];
/*
样例运行
5
7
3 8
8 1 0
2 7 4 4 
4 5 2 6 5
结果是30 
*/
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			cin>>D[i][j];//输入每一行数字三角形的每一个数值 
		}
	}
	
	for(int i=1;i<=n;i++)//最后一行初始化 
	{
		maxSum[i]=D[n][i];
	}
	for(int i=n-1;i>=1;i--)//注意是从底部往上递推 ,而且是倒数第二行
	{
		for(int j=1;j<=i;j++)
		{
			maxSum[j]=max(maxSum[j],maxSum[j+1])+D[i][j];
		}
	 } 
	 cout<<maxSum[1]<<endl;
	
	return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数字三角形问题是一个经典的动态规划问题。假设输入的数字三角形为一个二维数组`triangle`,其中`triangle[i][j]`表示第`i`行第`j`列的数字。在该数字三角形中,每个数字只能向下或向右下方移动,要求从顶部到底部的路径上数字之和最大。 动态规划的思路是从底向上逐层计算每个数字的最优解,最终得到顶部到底部的路径上数字之和的最大值。具体算法步骤如下: 1. 从数字三角形的底部开始,将底部每个数字作为子问题的最优解。即`dp[i][j] = triangle[i][j]`。 2. 从倒数第二行开始,对于每个数字`triangle[i][j]`,计算出它到底部路径上的最优解,即`dp[i][j] = triangle[i][j] + max(dp[i+1][j], dp[i+1][j+1])`。 3. 最终得到的`dp[0][0]`即为顶部到底部的路径上数字之和的最大值。 以下是使用C语言实现的代码: ```c #include <stdio.h> #include <stdlib.h> int main() { int n; // 数字三角形的行数 scanf("%d", &n); int triangle[n][n]; // 存储数字三角形 for (int i = 0; i < n; i++) { for (int j = 0; j <= i; j++) { scanf("%d", &triangle[i][j]); } } int dp[n][n]; // 存储每个数字的最优解 for (int i = 0; i < n; i++) { dp[n-1][i] = triangle[n-1][i]; // 底部数字的最优解为它本身 } for (int i = n-2; i >= 0; i--) { for (int j = 0; j <= i; j++) { dp[i][j] = triangle[i][j] + max(dp[i+1][j], dp[i+1][j+1]); // 计算每个数字的最优解 } } printf("%d", dp[0][0]); // 输出顶部到底部的路径上数字之和的最大值 return 0; } ``` 其中,`max()`函数为C语言内置的求最大值的函数,可以使用以下代码实现: ```c int max(int a, int b) { return a > b ? a : b; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值