HOJ 1058 Number Triangles

实战 Java 并发编程
实战为导向,从Java 并发原理出发,并集合开发实践,全面剖析 Java 并发编程。
wangxiaoming

                         HOJ 1058   Number  Triangles     


题目链接:点击打开链接


题目大意: 根据下面的三角形 ,计算从顶断到达底端的所有路径 出现的最大和 每一步只能往左下或者右下走 
INPUT :第一行 包含一个数字R 表示的是数据的行数  每一行 跟随的输入时三角形的行号 所有的数据位非负而且 不大于100
OUTPUT : 输出 这个搜索中出现的最大数

解题思路: 使用DP 进行解题  ,拥有两种性质  ,一最优子结构 ,另一个是 重叠子问题 
解题方法:写出动态规划方程  2、 然后自底向上进行计算 ,根据得到的信息构造 出最优解
  这道题的关键在于找到动态方程   : dp[i][j] = maze[i][j] + max(dp[i+1] [j] ,dp[i+1][j+1]);
下面先给出 没有AC 的代码:
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define Max 1003
int dp[Max][Max];
int maze[Max][Max];

int main()
{
    memset(dp, 0, sizeof(dp));
    memset(maze, 0, sizeof(maze));
    int r;
    int i, j;
    while(cin>>r)
    {//输入数据
        for(i = 0 ; i < r; i++)
        {
            for(j = 0 ; j <= i; j++)
            {
                cin>>maze[i][j];
            }
        }//自底向上进行搜索
        for(i = r-1; i>=0; i--)
        {
            for(j = 0 ; j <= i; j++)
            {
                dp[i][j] = maze[i][j] + max(dp[i+1][j], dp[i+1][j+1]);
            }
        }
        cout<<dp[0][0]<<endl;
    }
    return 0;
}


下面解释下为什么 , 这个以后解释 因为我也不知道为什么。。。。
下面给出一种子顶向下的解法:
 这种解法的状态方程式  dp[i][j] =  max(dp[i-1][j], dp[i-1][j-1])  + maze[i][j]   折两个状态方程如何理解  以后 再 说 。。。。
现在给出代码 ,好吧 是参考别人写的。。。
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define Max 1004

int maze[Max][Max], dp[Max][Max];
int main()
{
    int r, i , j;
    while(cin>>r)
    {
        for(i = 0 ; i < r ; i++)
        {
            for(j = 0 ; j <= i ; j++)
            {
                cin>>maze[i][j];
            }
        }
        //下面开始进行搜素
        for(i = 0 ; i < r; i++)
        {
            for(j = 0 ; j <= i; j++)
            {
                if(j == 0 && i== 0)
                {//初始化
                   dp[i][j] = maze[i][j];
                }
                if( j == 0)
                {
                    //在最左端开始进行搜索没有往左下的只有往下搜索的
                    dp[i][j] = dp[i-1][j] + maze[i][j];
                }
                else
                {
                     dp[i][j] = max(dp[i-1][j], dp[i-1][j-1]) + maze[i][j] ;
                }
            }
        }
        //完成上面的搜索之后就要判断最后的结果了
        //最大值只可能在最后一行产生
        int ans = 0;
        for(i = 0 ; i < r; i++)
        {
            if(dp[r-1][i] > ans)
            {
                ans = dp[r-1][i];
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}



 下面解释一下  第一个代码为什么 出现问题:
自底向上进行搜索 加上 三角形是 非负的因此 每次加上一个最大值 那么 到最后一定会是最大  的  而第一段代码 加的是最大 但是却把maze 认为最大加入进去了 ,这样是不合理的 ,下面的代码十分简洁明了

给出正确代码:
#include <cstdio>
#include <algorithm>
using namespace std;

const int MAX = 1024;

int main()
{
    int n, i, j;
    int tri[MAX][MAX];
    
    while(scanf("%d", &n) != EOF) {
        for(i = 0; i < n; i++)
			for(j = 0; j <= i; j++) scanf("%d", &tri[i][j]);
        for(i = n-1; i > 0; i--)
            for(j = 0; j < i; j++)
                tri[i-1][j] += max(tri[i][j],tri[i][j+1]);
        printf("%d\n", tri[0][0]);
    }

    return 0;
}


  
wangxiaoming CSDN认证博客专家 架构 Spring Boot Redis
博客是很好的总结和记录工具,如果有问题,来不及回复,关注微信公众号:程序员开发者社区,获取我的联系方式,向我提问,也可以给我发送邮件,联系 1275801617@qq.com
©️2020 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值