zoukankan      html  css  js  c++  java
  • 三角形问题

        有一个三角形数阵,行数和列数相等,第n行有n个数字,现在从上顶点,也就是第一行第一列出发,只能向左下或者向右下走到下一行,一直走到末尾,求怎么能使路径上的数字和最大,求这个最大值。

    第一行是一个数m,代表测试次数;对于每一次测试:第一行是一个数n(1<n<100),代表这个三角形数阵有n行,接着是n行的一个三角形数阵(对于每一个数都有1<Aij<100)。

    例如:输入:

            1

            5

            7

            3   8

            8   1   0

            2   7   4   4

            4   5   2   6   5

           输出:

            30

    对于这个问题,很容易想到用dfs,一条路径一条路径的找下去,最后得到那个最大值,所以写出了以下的程序:

    #include<stdio.h>
    int a[100][100]={0},i,j,k,m,n;
    int max=0,ans;
    void dfs(int x,int y, int ans)
    {
        ans+=a[x][y];
        if(x==n-1)
        {
            if(max<ans)
            max=ans;
        }
        else
        {
            dfs(x+1,y,ans);
            dfs(x+1,y+1,ans);
        }
    }
    main()
    {
        scanf("%d",&m);
        while(m--)
        {
            scanf("%d",&n);
            for(i=0;i<n;i++)
            {
                for(j=0;j<=i;j++)
               {
                    scanf("%d",&a[i][j]);
               }
            }
            dfs(0,0,0);
            printf("%d
    ",max);
         }
    }

     

        然后带入样例,发现是对的,但是,忽略了一点:时间。对,如果测试一个有99行的样例,那么会发现结果会弹出的非常慢,为什么呢?

    用数学方法算算就会知道:99行的样例一共会有2的98次方个路径,这么多路径,对于计算机来说也是较为庞大的,更何况要去找那个最大值,

    就更不容易了!

        那怎么去做这个题呢?既然要找最大值,那肯定走到每一个位置都有一个最大值,从头去找那个最大值不好找那何不直接从最后一行退回去找呢?

    除了存放数阵的数组外,再定义一个数组,同样有n行,但是每个位置存放着倒着走走到当前的最大值,这样一层一层往上,这个数组的第一行的那个数

    肯定就是所有路径的最大值了;

    例如:

    对于:

            7                        的路径最大值数阵为:          30

            3   8                                                  23        21

            8   1   0                                              20        13       10

            2   7   4   4                                          7         12       10       10

            4   5   2   6   5                                      4          5       2        6        5      

            用这个思路,很容易就写出了以下的程序:

    #include<stdio.h>
    int a[100][100]={0},b[100][100],i,j,k,m,n;
    int max(int x,int y)
    {
        if(x>y)
        return x;
        else
        return y;
    }
    void d(int n)
    {
        for(i=0;i<n;i++)
            b[n-1][i]=a[n-1][i];
        for(i=n-2;i>=0;i--)
        {
            for(j=i;j>=0;j--)
            b[i][j]=a[i][j]+max(b[i+1][j],b[i+1][j+1]);
         }
    }
    main()
    {
        scanf("%d",&m);
        while(m--)
        {
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            for(j=0;j<=i;j++)
            {
                scanf("%d",&a[i][j]);
            }
         }
         d(n);
        printf("%d
    ",b[0][0]);
        }
    }

     

    可以看到,对于这个程序,即使有100行,也只需要运算4950次,将数组   b    填满,就可以得到答案。多用dfs就会发现,

    用dfs很容易时间超限,这时候,就需要用其他算法将其代替。

  • 相关阅读:
    mv、umask、chattr、lsattr命令
    mkdir、whoami、touch
    man命令
    hostname、uname、dmesg、fdisk
    find命令
    etc下
    echo命令
    date 、cal、bc
    表白程序源代码,android
    设置Windows 8.1屏幕自己主动旋转代码, Auto-rotate function code
  • 原文地址:https://www.cnblogs.com/xujunming/p/6159986.html
Copyright © 2011-2022 走看看