zoukankan      html  css  js  c++  java
  • 数字三角形_递归_递推(动态规划)

    输入格式:

    5 // 三角形行数,下面是三角形
    7
    3 8
    8 1 0
    2 7 4 4
    4 5 2 6 5

    三角形的行数大于1小于等于100,数字为 0 – 99。
    要求输出最大和,不必给出具体路径。


    思路

    • D(r,j):第r行第j个数字(r,j从1开始算)
    • MaxSum(r,j):从D(r,j)到底边的各条路径中,最佳路径的数字之和

    问题:求MaxSum(1,1)

    D(r,j)出发,下一步只能走D(r+1,j)或者D(r+1,j+1)
    对于N行的三角形:

    if(r == N)
        MaxSum(r,j) = D(r,j)
    else
        MaxSum(r,j) = Max{ MaxSum(r+1,j), MaxSum(r+1,j+1) } + D(r,j)

    递归

    #include<iostream>
    #include<algorithm>
    #define MAX 101
    using namespace std;
    
    int D[MAX][MAX];
    int n;
    
    int MaxSum(int i, int j) {
        if(i == n)
            return D[i][j];
        int x = MaxSum(i+1,j);
        int y = MaxSum(i+1,j+1);
        return max(x,y) + D[i][j];
    }
    
    int main(){
        cin>>n;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=i; j++)
                cin>>D[i][j];
        cout<< MaxSum(1,1) <<endl;
        return 0;
    }
    

    改进
    每算出一个MaxSum(r,j)就保存起来,下次用到其值的时候直接取用,则可免去重复计算。


    记忆递归型动态规划

    #include<iostream>
    #include<algorithm>
    #define MAX 101
    using namespace std;
    
    int D[MAX][MAX];
    int n;
    int maxSum[MAX][MAX];
    
    int MaxSum(int i, int j) {
        if(maxSum[i][j] != -1)
            return maxSum[i][j];
        if(i == n)
            maxSum[i][j] = D[i][j];
        else {
            int x = MaxSum(i+1,j);
            int y = MaxSum(i+1,j+1);
            maxSum[i][j] = max(x,y) + D[i][j];
        }
        return maxSum[i][j];
    }
    
    int main() {
        cin>>n;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=i; j++) {
                cin>>D[i][j];
                maxSum[i][j] = -1;
            }
        cout<< MaxSum(1,1) <<endl;
        return 0;
    }
    

    30
    23 21
    20 13 10
    7 12 10 10
    4 5 2 6 5

    递推型动态规划

    #include<iostream>
    #include<algorithm>
    #define MAX 101
    using namespace std;
    
    int D[MAX][MAX];
    int n;
    int maxSum[MAX][MAX];
    
    int main() {
        cin>>n;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=i; j++)
                cin>>D[i][j];
        for(int i=1; i<=n; i++)
            maxSum[n][i] = D[n][i];
        for(int i=n-1; i>=1; i--)
            for(int j=1; j<=i; j++)
                maxSum[i][j] = max(maxSum[i+1][j],maxSum[i+1][j+1]) + D[i][j];
        cout<<maxSum[1][1]<<endl;
    }
    

    空间优化动态规划
    D的第n行替代maxSum

    #include<iostream>
    #include<algorithm>
    #define MAX 101
    using namespace std;
    
    int D[MAX][MAX];
    int n;
    int *maxSum;
    
    int main() {
        cin>>n;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=i; j++)
                cin>>D[i][j];
        maxSum = D[n];  // maxSum指向第n行
        for(int i=n-1; i>=1; i--)
            for(int j=1; j<=i; j++)
                maxSum[j] = max(maxSum[j], maxSum[j+1]) + D[i][j];
        cout<<maxSum[1]<<endl;
        return 0;
    }
    

    北大的公开课真心不错,感觉比现在上的算法课好很多(●’◡’●)

  • 相关阅读:
    硬盘内部结构简析
    python之集合
    Python中的浅拷贝与深拷贝
    Python内存管理机制
    python之编码decode
    project euler之Large sum
    project euler之 网格中最大的产品
    project euler之 素数的总和
    project euler之特殊的毕达哥拉斯三重奏
    project euler之系列中最大的产品
  • 原文地址:https://www.cnblogs.com/Genesis2018/p/9079806.html
Copyright © 2011-2022 走看看