• 算法问题实战策略 TRIANGLEPATH 动态规划入门题


    地址 https://algospot.com/judge/problem/read/TRIANGLEPATH (leetcode acwing 均有类似题目可供练习)

    我们先从 暴力遍历开始说起

    每当你处于一个点 有两个选择 选择下面的数字或者选择右下的数字(x+1   ||  x+1  y+1)

    那么每个选择都计算 最后得出sum最大的值就是答案

    很明显 这个会TLE

     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 
     5 
     6 using namespace std;
     7 
     8 const int MAX_N = 100010;
     9 
    10 vector<int> v[MAX_N];
    11 int n, m;
    12 int maxsum = -9999999;
    13 
    14 void dfs(int x, int y, int sum) {
    15     if (x == m+1  && y < x) {
    16         maxsum = max(maxsum, sum);
    17         return;
    18     }
    19     if (x >= m || y > x)
    20     {
    21         return;
    22     }
    23 
    24     sum += v[x][y];
    25 
    26     dfs(x+1,y,sum);
    27     dfs(x+1, y + 1, sum);
    28 }
    29 
    30 void solve()
    31 {
    32     int sum = 0;
    33     dfs(0, 0, sum);
    34 
    35     cout << maxsum << endl;
    36 }
    37 
    38 int main()
    39 {
    40     cin >> n;
    41     while (n--) {
    42         cin >> m;
    43         int len = 1;
    44         maxsum = -9999999;
    45         for (int i = 0; i < MAX_N; i++) {
    46             v[i].clear();
    47         }
    48 
    49         for (int i = 0; i < m; i++) {
    50             for (int j = 0; j < len; j++) {
    51                 int t; cin >> t; v[i].push_back(t);
    52             }
    53             len++;
    54         }
    55 
    56         solve();
    57     }
    58 
    59     return 0;
    60 }
    View Code

    原因在哪里呢?在如下的三角形里 路线有以下几种

    1
    2 3
    4 5 6
    7 8 9 10 
    1->2->4->7
    1->2->4->8
    1->2->5->8
    1->2->5->9
    1->3->5->8
    1->3->5->9
    1->3->6->9
    1->3->6->10

    我们可以看到 1->2 1->3的路线重复计算好几次 每次都会去求和

    那么我们使用一个表格记录走到2的位置和走到3的位置的最大和 是否就可以避免重复计算

    同样其他格子也使用如此思路 

    再进行观察

    7 8 9 10的记录取决于 他们能够倒推到的 4 5 6格子记录的最大和

    4 5 6 的记录取决于 他们能够倒推到的 2  3 格子记录的最大和

    2 3的记录取决于 他们能够倒推到的 1 格子记录的最大和

    1 的格子是确认的 他的最大和就是他自己

    有两种推导公式 如下

    /*for (int i = m - 1; i >= 0; i--) {
            for (int j = i; j >= 0; j--) {
                v[i][j] = max(v[i + 1][j], v[i + 1][j + 1]) + v[i][j];
            }
        }
        cout << v[0][0] << endl;*/
        //====================================================================
        /*
        for (int i = 0; i < m; i++) {
            for (int j = 0; j <= i; j++) {
                if (i - 1 >= 0 && j -1 >=0) {
                    dp[i][j] = max( dp[i-1][j]+dp[i][j] , dp[i - 1][j-1] + dp[i][j]);
                }
                else if (i - 1 >= 0) {
                    dp[i][j] = dp[i - 1][j]+dp[i][j];
                }
            }
        }
    
        int ret = -999999;
        for (int i = 0; i < m; i++) {
            ret = max(ret, dp[m - 1][i]);
        }
        cout << ret << endl;

    全部代码

     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 
     5 
     6 using namespace std;
     7 
     8 const int MAX_N = 300;
     9 
    10 vector<vector<int>> v(MAX_N,vector<int>(MAX_N));
    11 int n, m;
    12 int maxsum = -9999999;
    13 
    14 vector<vector<int>> dp(MAX_N,vector<int>(MAX_N));
    15 
    16 
    17 
    18 
    19 
    20 void solve()
    21 {
    22     /*for (int i = m - 1; i >= 0; i--) {
    23         for (int j = i; j >= 0; j--) {
    24             v[i][j] = max(v[i + 1][j], v[i + 1][j + 1]) + v[i][j];
    25         }
    26     }
    27     cout << v[0][0] << endl;*/
    28     //====================================================================
    29     /*
    30     for (int i = 0; i < m; i++) {
    31         for (int j = 0; j <= i; j++) {
    32             if (i - 1 >= 0 && j -1 >=0) {
    33                 dp[i][j] = max( dp[i-1][j]+dp[i][j] , dp[i - 1][j-1] + dp[i][j]);
    34             }
    35             else if (i - 1 >= 0) {
    36                 dp[i][j] = dp[i - 1][j]+dp[i][j];
    37             }
    38         }
    39     }
    40 
    41     int ret = -999999;
    42     for (int i = 0; i < m; i++) {
    43         ret = max(ret, dp[m - 1][i]);
    44     }
    45     cout << ret << endl;
    46     */
    47 }
    48 
    49 int main()
    50 {
    51     cin >> n;
    52     while (n--) {
    53         cin >> m;
    54         int len = 1;
    55         maxsum = -9999999;
    56         for (int i = 0; i < MAX_N; i++) {
    57             for (int j = 0; j < MAX_N; j++) {
    58                 v[i][j] = 0;
    59                 //dp[i][j] = 0;
    60             }
    61         }
    62 
    63         for (int i = 0; i < m; i++) {
    64             for (int j = 0; j < len; j++) {
    65                 cin >> v[i][j];
    66                 dp[i][j] = v[i][j];
    67             }
    68             len++;
    69         }
    70 
    71         solve();
    72     }
    73 
    74     return 0;
    75 }
    View Code
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    史上不全 ——LINQ to SQL语句
    asp.net mvc 5 后台操作
    asp.netmvc 前台基本控件操作
    ef6+asp.net MVC5+bootstrap3
    个人改造方法调用接口文档
    mvc开发过程中遇到的一些小问题修改
    FileUpload1 在部分浏览器中实现多选
    时间字段 输入空值显示为1900-1-1的解决办法,在asp.net 后台处理
    ASP.NET-C#中字符串操作
    保留多行文本框的换行与空格样式,并转义HTML标记的尖括号
  • 原文地址:https://www.cnblogs.com/itdef/p/12102869.html
Copyright © 2020-2023  润新知