zoukankan      html  css  js  c++  java
  • hdu 2084 数塔 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2084

          经典的DP入门题。

          最近学起DP,做回这道题目,用的是自顶向上的方法来求解,发现代码很长,不过时间短了,这应该就是传说中的“以空间换时间”的说法吧。个人觉得,这比较符合人的思考模式,不过真的很繁琐,由于不知道最后一行中最大和的具体位置,还要比较找出。

         状态转移方程是(设f(i, j)为三角形上从点(i,j)出发向下走的最大和路径, a(i, j)表示原始输入的第 i 行第 j 列的数 :

                     f(i, j) = a(i, j) + max{f(i-1, j-1), f(i-1, j)}      i != j  (每行里除第一和最后的处于中间位置的数

                                a(i, j)+ f(i-1, j)                               j = 0   (每行里的第一个数)

                                a(i, j) + f(i-1, j-1)                             j = i   (每行里的最后一个数)

                               

        

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     int c, i, j, n, a[105][105], maxsum;
     7     while (scanf("%d", &c) != EOF)
     8     {
     9         while (c--)
    10         {
    11             scanf("%d", &n);
    12             for (i = 0; i < n; i++)
    13             {
    14                 for (j = 0; j <= i; j++)
    15                     scanf("%d", &a[i][j]);
    16             }
    17             for (i = 1; i < n; i++)
    18             {
    19                 for (j = 0; j <= i; j++)
    20                 {
    21                     if (j == 0)    //每行的第一个数只能从它的正上一行+当前行的数
    22                     {
    23                         a[i][j] = a[i-1][j] + a[i][j];
    24                     }
    25                     else if (i == j) //每行的最后一个数只能从它的左上一行+当前行的数
    26                         a[i][j] = a[i-1][j-1] + a[i][j];
    27                     else
    28                     {
    29                         if (a[i-1][j] > a[i-1][j-1])   //上一行的左边的数和上一行正对着的数比较
    30                             a[i][j] = a[i-1][j] + a[i][j];
    31                         else
    32                             a[i][j] = a[i-1][j-1] + a[i][j];
    33                     }
    34                 }
    35             }
    36             maxsum = -100;
    37             for (j = 0; j <= n-1; j++)
    38                 if (maxsum < a[n-1][j])
    39                     maxsum = a[n-1][j];
    40             printf("%d\n", maxsum);    
    41         }
    42     }
    43     return 0;
    44 }

         自底向上的求法:

         (连特殊位置的判断都不用考虑了,而且保证最后输出的a[0][0]一定是最大的)

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     int c, i, j, n, a[105][105];
     7     while (scanf("%d", &c) != EOF)
     8     {
     9         while (c--)
    10         {
    11             scanf("%d", &n);
    12             for (i = 0; i < n; i++)
    13             {
    14                 for (j = 0; j <= i; j++)
    15                     scanf("%d", &a[i][j]);
    16             }
    17             for (i = n - 2; i >= 0; i--)
    18             {
    19                 for (j = 0; j <= i; j++)
    20                 {
    21                     if (a[i+1][j] > a[i+1][j+1])
    22                         a[i][j] = a[i+1][j] + a[i][j];
    23                     else
    24                         a[i][j] = a[i+1][j+1] + a[i][j];
    25                 }
    26             }
    27             printf("%d\n", a[0][0]);    
    28         }
    29     }
    30     return 0;
    31 }

       

  • 相关阅读:
    14 微服务电商【黑马乐优商城】:day06-使用nginx反向代理并掌握cors解决跨域
    Docker容器化【Docker安装与启动&Docker镜像与容器相关命令】
    [LeetCode]Palindrome Number 验证回文数
    C++结构体定义构造函数
    C++中explicit关键字的使用
    C++ const关键字
    图像梯度(Image Gradient)
    ORB特征点匹配
    c++:internal compiler error:killked(program cclplus) 解决办法
    最小二乘通俗解释
  • 原文地址:https://www.cnblogs.com/windysai/p/3091403.html
Copyright © 2011-2022 走看看