蓝桥杯:数字三角形

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6buE5p-v5p-v,size_20,color_FFFFFF,t_70,g_se,x_16

        看到这道题,脑海中想到的就是dp,第一步就可以开始找规律,但这时候发现一个有意思的地方,题目里说:“路径上的每一步只可沿左斜线向下或右斜线向下走”,然而看到输入样例的时候

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

会发现实际上其实是:“只能向下走或者向右下走”。

        此时我们可以定义一个二维数组:路径和sum[行][列],到这一行列的方法有两种,一种是从正上方sum[行-1][列],一种是从左上方sum[行-1][列-1],可以发现,到第一行第一列的时候,没有上方和左上方,所以可以初始化:

sum[0][0]=n[0][0];//n是存放题目提供的数字三角形的数组

而且还可以发现,第一列只能从上方来,每行最后一列的只能从左上方来,所以需要特殊对待:

for(int i=1;i<N;i++)
	{
		sum[i][0]=sum[i-1][0]+n[i][0];
		sum[i][i]=sum[i-1][i-1]+n[i][i];
	}

而初始化第一项和特殊项之后,也可以发现普通项是从sum[2][1]开始,既可以从上方来,也可以从左上方来,题目要求最大路径和,所以此时需要判断哪条路来的路径和最大,此时可以使用:

for(int i=2;i<N;i++)
	{                       //小于i是因为最后一列已经初始化了,不需要更改
		for(int j=1;j<i;j++)//而且数字三角形的最后一列是和行相等的
		{
			sum[i][j]=sum[i-1][j]>sum[i-1][j-1]?sum[i-1][j]:sum[i-1][j-1];
            //判断哪条路径来的路径和最大
			sum[i][j]+=n[i][j];
            //不要忘记加上路径到达这里的数字
		}
	}

最后判断最后一行哪个数字最大,就是从最上面到最下面最大路径和了。

        上完整代码:

#include <bits/stdc++.h>

using namespace std;

int main()
{
	int N,max=0;
 	cin >> N;
 	int n[N][N]={0};
	for(int i=0;i<N;i++)
	{
		for(int j=0;j<i+1;j++)
		{
			cin >> n[i][j];
		}
	}
	
	int sum[N][N]={0};
	//到n[i][j]时,最大路径和是sum[i][j]=max(sum[i-1][j],sum[i-1][j-1])+n[i][j]
	//sum[N-1][j]是要的答案
	//初始化
	sum[0][0]=n[0][0];
	for(int i=1;i<N;i++)
	{
		sum[i][0]=sum[i-1][0]+n[i][0];
		sum[i][i]=sum[i-1][i-1]+n[i][i];
	}
 for(int i=2;i<N;i++)
	{                       //小于i是因为最后一列已经初始化了,不需要更改
		for(int j=1;j<i;j++)//而且数字三角形的最后一列是和行相等的
		{
			sum[i][j]=sum[i-1][j]>sum[i-1][j-1]?sum[i-1][j]:sum[i-1][j-1];
            //判断哪条路径来的路径和最大
			sum[i][j]+=n[i][j];
            //不要忘记加上路径到达这里的数字
		}
	}
	for(int j=0;j<N;j++)//找最大路径和
	{
		if(sum[N-1][j]>max)
		{
			max=sum[N-1][j];
		}
	}
	cout << max;

 	return 0;
}

 

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AtlanticDrift

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值