• [ACM_动态规划] 数字三角形(数塔)_递推_记忆化搜索


    1、直接用递归函数计算状态转移方程,效率十分低下,可以考虑用递推方法,其实就是“正着推导,逆着计算”
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define maxn 1000+5
    int n;
    int a[maxn][maxn];
    int d[maxn][maxn];
    int main(){
        
        for(;cin>>n && n;){
            memset(d,0,sizeof(d));
            int i,j;
    
            for(i=1;i<=n;i++){     //输入
                for(j=1;j<=i;j++){
                    cin>>a[i][j];
                }
            }
    
            for(j=1;j<=n;j++){     //计算最底层d[][]值
                d[n][j]=a[n][j];
            }
    
            for(i=n-1;i>=1;i--){   //从下向上计算d[][]值
                for(j=1;j<=i;j++){
                    d[i][j]=a[i][j]+max(d[i+1][j],d[i+1][j+1]);
                }
            }
            cout<<d[1][1]<<'
    ';
        }
    }
    View Code
    2、记忆化搜索虽然也是递归,但同时把计算结果保存在d[][]中,可以保证每个节点只访问一次(不必事先确定各状态计算顺序,但需要记录每个状态是否计算过,本题把d[][]初始为-1,>=0则算过。
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define maxn 1000+5
    int n;
    int a[maxn][maxn];
    int d[maxn][maxn];
    int D(int i,int j){
        if(d[i][j]>=0)return d[i][j];                    
        return d[i][j]=a[i][j]+(i==n ? 0 : max(D(i+1,j),D(i+1,j+1)));    //记忆化搜索要保存每次计算结果
    }
    int main(){
        
        for(;cin>>n && n;){
            memset(d,-1,sizeof(d));             //初始化为-1,也是为记忆化搜索做的标记,当>=0时直接返回d[][];
            int i,j;
    
            for(i=1;i<=n;i++){
                for(j=1;j<=i;j++){
                    cin>>a[i][j];
                }
            }
            cout<<D(1,1)<<'
    ';
        }
    }
    View Code
  • 相关阅读:
    人机博弈,吃子棋游戏(一)基本介绍
    cesm下载备注
    mysql数据库批量高速插入
    持续学习
    顺序表的功能实现
    Broccoli &amp; Babel使用演示样例
    rk3188调试记录
    Operation not allowed on a unidirectional dataset错误?
    dbExpress操作中用TDBGrid显示数据
    dbexpress连接mysql提示Operation not allowed on a unidirectional dataset
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/3219154.html
Copyright © 2020-2023  润新知