zoukankan      html  css  js  c++  java
  • 【9901】数塔问题

    Time Limit: 10 second
    Memory Limit: 2 MB

    问题描述
    设有一个三角形的数塔,顶点结点称为根结点,每个结点有一个整数数值。从顶点出发,在每一个结点可以选择向左走或者向右走一直走到底层,要求找出一条路径,使路径上的值最大。

    Input

    第一行有数塔层数n,接下来若干行为数塔。

    Output

    输出一行数据,即路径的最大值(包括一个换行符)

    Sample Input

    5
    13
    11 8
    12 7 26
    6 14 15 8
    12 7 13 24 11
    

    Sample Output

    max=86
    
    

    Sample Input2

    10
    1
    121 18
    12 72 26
    63 14 15 8
    125 57 13 24 11
    11 12 63 58 47 45
    0 152 365 12 36 59 987
    0 1 23 4 5 6 7 8
    25 36 99 87 44 51 23 69 65
    10 12 35 92 15 2654 21 30 25 69
    
    

    Sample Output2

    max=3401
    

    【题解】

    这题是动态规划。先看一下数塔的样子如下

    如果只有前两行,我们可以很快的得出来答案是24.

    如果又加了一行。则我们不能肯定就是从13->11->12了。

    我们在右边也要看一下。因为可能出现一个变态的数字让右边的路径也能更优。

    于是我们开一个f[i][j]数组,f[2][1] = 24 f[2][2] = 21;

    这样我们就记录了走到第二行第1个数字的最优解,和走到第二行第二个数字的最优解。

    然后我们看第三行,可以看到12只能由2,1走到。那么f[3][1] = f[2][1]+a[3][1],a[3][1] = 12;

    然后是第三行的第二个数字7,7可以由11 和 8走到,于是我们就判断一下f[2][1]和f[2][3] 它们分别加上a[3][2]后哪一个会比较大。然后把它赋值给f[3][2]。

    然后是第三行的第三个数字26,26只能由8走到。于是f[3][3] = f[2][2] + a[3][3];

    这样我们就求出了到达第3行第j列的所有位置的最优解。依照我们处理第三行的规律。

    我们可以得出第四行的最优解。

    由此得出动态转移方程

    f[i][j] = max(f[i-1][j-1],f[i-1][j]);

    【代码】

    #include <cstdio>
    #include <stdlib.h>
    
    int n,a[100][100],f[100][100],ans;
    
    void input_data()
    {
        scanf("%d",&n);
        for (int i = 1;i <= n;i++)
            for (int j = 1;j <=i;j++) //读入数字矩阵
                scanf("%d",&a[i][j]);
    }
    
    int ma_x(int x,int y) //获取x和y中的更大值、
    {
        if (x > y)
            return x;
                else
                    return y;
    }
    
    void get_ans()
    {
        f[1][1] = a[1][1]; //第一排的第一个数字用于作为动规的奠基
        for (int i = 2;i <= n;i++)
            for (int j = 1;j <=i;j++) //然后根据状态转移方程求出下面的f[i][j]
                f[i][j] = ma_x(f[i-1][j-1]+a[i][j],f[i-1][j]+a[i][j]);
        ans = f[n][1];
        for (int i = 2;i <= n;i++) //在最后一层中找答案(最大值)
            ans = ma_x(ans,f[n][i]);
    }
    
    void output_ans()
    {
        printf("max=%d
    ",ans);
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        input_data();
        get_ans();
        output_ans();
        return 0;
    }
    


     

  • 相关阅读:
    linux shell在while中用read从键盘输入
    ubuntu14.04折腾迅雷xware
    select与epoll分析
    ubuntu 14.04下练习lua
    C++中的重载、覆盖、隐藏
    删除ubuntu旧内核
    fcntl函数加文件锁
    系统中断与SA_RESTART
    linux使用共享内存通信的进程同步退出问题
    leetcode-easy-others-268 Missing Number
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632415.html
Copyright © 2011-2022 走看看