• 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 }

       

  • 相关阅读:
    机器学习算法优秀性:衡量指标
    MapReduce and Pregel
    K-d 树对聚类算法进行预处理
    论文中的算法描述 By 薛磊
    批判性思维《描述性假设》
    论文中的数学符号使用
    HOOK别人的dylib(HOOK cydia里面的插件)
    关于某听书软件的开通20年会员的心路历程
    Aspects 源码学习
    Undefined symbols for architecture arm64(其cpu架构)
  • 原文地址:https://www.cnblogs.com/windysai/p/3091403.html
Copyright © 2020-2023  润新知