• 动态规划入门--数字三角形问题


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

    (图1)


    图1给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。

    注意:路径上的每一步只能从一个数走到下一层上和它最近的左边的那个数或者右边的那个数。 Input 输入的是一行是一个整数N (1 < N <= 100),给出三角形的行数。下面的N行给出数字三角形。数字三角形上的数的范围都在0和100之间。 Output 输出最大的和。 Sample Input

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

    Sample Output

    30

    方法一:递推转移方程
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn =101;
     7 int s[maxn][maxn];
     8 int dp[maxn][maxn];
     9 int n;
    10 
    11 int main(){
    12     scanf("%d",&n);
    13     memset(dp,0,sizeof(dp));
    14     memset(s,0,sizeof(s));
    15     for( int i=1; i<=n; i++ ){
    16         for( int j=1; j<=i; j++ ){
    17             scanf("%d",&s[i][j]);
    18         }
    19     }
    20     
    21     for( int i=1; i<=n; i++ ){
    22         dp[n][i]=s[n][i];
    23     }
    24     for( int i=n-1; i>=1; i-- ){
    25         for( int j=1; j<=i; j++ ){
    26             dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+s[i][j];
    27         }
    28     }
    29     printf("%d
    ",dp[1][1]);
    30     return 0;
    31 }

     方法二:记忆化搜索递归

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn =101;
     7 int s[maxn][maxn];
     8 int dp[maxn][maxn];
     9 int n;
    10 
    11 /*记忆化搜索*/
    12 int solve(int i,int j){
    13     if(dp[i][j]>=0) return dp[i][j];
    14     return dp[i][j]=s[i][j]+(i==n?0:max(solve(i+1,j),solve(i+1,j+1)));
    15 }
    16 
    17 int main(){
    18     scanf("%d",&n);
    19     memset(dp,-1,sizeof(dp));
    20     memset(s,0,sizeof(s));
    21     for( int i=1; i<=n; i++ ){
    22         for( int j=1; j<=i; j++ ){
    23             scanf("%d",&s[i][j]);
    24         }
    25     }
    26     int ans=solve(1,1);
    27 //    for( int i=1; i<=n; i++ ){
    28 //        dp[n][i]=s[n][i];
    29 //    }
    30 //    for( int i=n-1; i>=1; i-- ){
    31 //        for( int j=1; j<=i; j++ ){
    32 //            dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+s[i][j];
    33             
    34 //        }
    35 //    }
    36 
    37     printf("%d
    ",ans);
    38     return 0;
    39 }
    有些目标看似很遥远,但只要付出足够多的努力,这一切总有可能实现!
  • 相关阅读:
    STL_算法_查找算法(lower_bound、upper_bound、equal_range)
    Kafka深度解析
    hdoj 1027 Ignatius and the Princess II 【逆康托展开】
    代码二次封装-xUtils(android)
    C++11新特性应用--介绍几个新增的便利算法(用于排序的几个算法)
    谨防串行的状态报告会
    hadoop中NameNode、DataNode和Client三者之间协作关系及通信方式介绍
    Kindeditor JS 取值问题以及上传图片后回调等
    MySQL 8.0.11 报错[ERROR] [MY-011087] Different lower_case_table_names settings for server ('1')
    爱的链条
  • 原文地址:https://www.cnblogs.com/Bravewtz/p/10564272.html
Copyright © 2020-2023  润新知