【蓝桥杯省赛真题】数字三角形(图形特征+动态规划)

【蓝桥杯省赛真题】数字三角形(图形特征+动态规划),第1张

文章目录

  • 一、题目


  • 二、解法分析

    • 1、图形特征
    • 2、动态规划

  • 三、代码



一、题目




二、解法分析

原本我的做法很复杂。






后来看到一位大佬非常简单的代码,才恍然大悟。


(果然能找规律的题就找规律!)

1、图形特征

如果直接看下面这个图形的话可能不太容易懂。




看下面这个就很好解释了。




每一行都有两种选择,向下走或者向右下走。


那么根据题意,我们要让向下走的步数和向右下走的步数之差不超过1。


数字三角形一共n行。


若n为奇数,设向下走的步数为x,向右下走的步数为y,则:

n-1是一个偶数,只有让x=y,才能使得x-y的绝对值小于等于1。



因此,向右下走的总步数就为(n-1)/2。



最后,停留的位置就是第n行,第(n-1)/2+1列。


若n为偶数,x+y同样等于n-1。



此时,n-1是一个奇数。


那么想让x-y的绝对值小于等于1,有两种情况



同理可得最后停留的位置就是第n行,第(n-1)/2+1列,或者第n行,第(n-1)/2+2列。


2、动态规划

从上面的分析中还可以得出,从起点到讨论出来的最后停留的位置,无论怎么走都是满足“向下走的步数和向右下走的步数之差不超过1”这个要求的(因为往右下走的步数确定了,往下走的步数也是确定的)。


所以,我们需要做的就是在这些路径中,找到一条数字之和最大的路径。


动态规划方程:


三、代码

#include 

using namespace std;
int n;
int a[103][103];
int main()
{
    cin>>n;
    int i,j;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=i;j++)
        {
            cin>>a[i][j];
        }
    }
    if(n%2==1)
    {
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=i;j++)
            {
                a[i][j]=max(a[i-1][j-1],a[i-1][j])+a[i][j];
            }
        }
        printf("%d\n",a[n][n/2+1]);
    }
    else{
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=i;j++)
            {
                a[i][j]=max(a[i-1][j-1],a[i-1][j])+a[i][j];
            }
        }
        printf("%d\n",max(a[n][n/2],a[n][n/2+1]));
    }
    return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/564688.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-06
下一篇 2022-04-06

发表评论

登录后才能评论

评论列表(0条)

保存