寒假每日一题 DP 数字三角形 2020-01-11

   日期:2021-01-13     浏览:93    评论:0    
核心提示:DP问题数字三角形2020-01-12

问题描述:

原题链接
给定一个如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大。

        7
      3   8
    8   1   0
  2   7   4   4
4   5   2   6   5

输入格式
第一行包含整数n,表示数字三角形的层数。

接下来n行,每行包含若干整数,其中第 i 行表示数字三角形第 i 层包含的整数。

输出格式
输出一个整数,表示最大的路径数字和。

数据范围
1≤n≤500,
−10000≤三角形中的整数≤10000

输入样例:

5
7
3 8
8 1 0 
2 7 4 4
4 5 2 6 5

输出样例:

30

我的分析:

刚开始接触动态规划,个人觉得动态规划有点递归的味道,记住每个阶段的状态,下一次情况和上一次的状态有关,解决状态规划需要知道状态转化(状态计算,下一次和和上一次状态之间的联系)
典型问题:最大最长子序列,最大值问题。

解决方案:

这个题目可以用下往上找的方式,既可以不用考虑负数,也可以不用像顺推一样考虑边界带来种种裂开的问题。用f数组记录状态。

我的代码:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N =510;
int a[N][N],f[N][N];
int n,m;
int main()
{ 
    cin>>n;
    for(int i=1;i<=n;++i){ 
        for(int j=1;j<=i;++j){ 
            cin>>a[i][j];
        }
    }
    //cout<<","<<endl;
    for(int i=1;i<=n;++i){ 
        f[n][i]=a[n][i];
    }
    //cout<<","<<endl;
    for(int i=n-1;i>=1;--i){ 
        for(int j=1;j<=i;++j){ 
            f[i][j]=max(f[i+1][j],f[i+1][j+1])+a[i][j];
        }
    }
    
    cout<<f[1][1]<<endl;
    return 0;
}

第二种简略版只需要一个数组:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N =510;
int f[N][N];
int n,m;
int main()
{ 
    cin>>n;
    //都从1开始,避免思路混乱,以后都这么用嘿嘿。
    for(int i=1;i<=n;++i){ 
        for(int j=1;j<=i;++j){ 
            cin>>f[i][j];
        }
    }
    for(int i=n-1;i>=1;--i){ 
        for(int j=1;j<=i;++j){ //这个地方循环的结束要搞清楚,第i行有i个数
            f[i][j]+=max(f[i+1][j],f[i+1][j+1]);
        }
    }
    cout<<f[1][1]<<endl;
    return 0;
}

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服