【题目链接】

ybt 1258:【例9.2】数字金字塔

【题目考点】

1. 记忆化搜索

2. 动态规划基本型

【解题思路】

思路1:一般深搜(非正确解

每到一个位置,更新加和,向左下,右下两个方向搜索。
搜索到最后一行,判断当前加和是否大于最大加和,更新最大加和。
该搜索过程实际上对很多问题重复计算了很多次,因而时间复杂度较高。只能解决小规模的问题,如果提交该代码的话,必定超时!

#include<bits/stdc++.h>
using namespace std;
#define N 1005
int a[N][N], r;
int maxSum, sum;//最大加和
//从第i,j位置开始搜索
void dfs(int i, int j)
{sum += a[i][j];if(i == r)//i==r时,是最下面一行{if(sum > maxSum)//更新最大加和maxSum = sum;}else//只要不是最后一行。{//i,j左下的位置是:i+1,j,右下的位置是:i+1,j+1dfs(i + 1, j);dfs(i + 1, j + 1);}sum -= a[i][j];
}
int main()
{cin>>r;for(int i = 1; i <= r; ++i){for(int j = 1; j <= i; ++j)cin>>a[i][j];}dfs(1, 1);cout<<maxSum;return 0;
}

思路2:记忆化递归

思路3:顺推法

思路4:逆推法

【题解代码】

解法1:记忆化递归

设二维数组sumMx,sumMx[i][j]记录i,j位置到底层的最大加和。

  • 递归问题为:求第i,j位置到底层的最大加和。
  • 递归函数中:
    • 如果在sumMx中已经记录了i,j位置到底层的最大加和,则直接返回该值。
    • 如果没有记录,那么最大加和为:“该位置左下方位置到底层的最大加和”,和“该位置右下方位置到底层的最大加和”中的最大值,加上该位置的值。而后记录该值。
      i,j的左下方位置:i+1,j,右下方位置:i+1,j+1,所以该表达式为:
      sumMx[i][j] = a[i][j] + max(dfs(i+1, j), dfs(i+1, j+1));
  • 递归退出条件:到达底层
#include<bits/stdc++.h>
using namespace std;
#define N 1005
int a[N][N], r;//a:原始数据,r:行数
int sumMx[N][N];//sumMx[i][j]:记录i,j位置到底层的最大加和
int maxSum, sum;//maxSum:最大加和,sum:临时加和
//求第i,j位置到底层的最大加和
int dfs(int i, int j)
{if(sumMx[i][j] == -1)//如果这里没有记录{if(i == r)//如果已经到底层sumMx[i][j] = a[i][j];//从该点到底层的最大加和就是该位置的值elsesumMx[i][j] = a[i][j] + max(dfs(i+1, j), dfs(i+1, j+1));}return sumMx[i][j];
}
int main()
{cin>>r;for(int i = 1; i <= r; ++i)for(int j = 1; j <= i; ++j)cin>>a[i][j];memset(sumMx, -1, sizeof(sumMx));//将sumMx数组初值设为-1,表示这里没有记录数据cout<<dfs(1, 1);return 0;
}

解法2:顺推法

  • 设二维数组sumMx,sumMx[i][j]记录从1,1位置到i,j位置的最大加和
  • 1,1到i,j位置的加和,为1,1到i,j位置左上右上两个位置的加和的最大值,加上i,j位置的值。
    i,j左上位置为i-1,j-1;右上位置为i-1,j
    所以有:sumMx[i][j] = max(sumMx[i-1][j-1], sumMx[i-1][j]) + a[i][j];
    初始情况sumMx[1][1] = a[1][1];
    以此可以推出从1,1到底层各位置的最大加和,取其中最大值即可。
#include<bits/stdc++.h>
using namespace std;
#define N 1005
int a[N][N], r;//a:原始数据,r:行数
int sumMx[N][N];//sumMx[i][j]:记录从1,1到i,j位置的最大加和
int mxVal;//最大加和
int main()
{cin>>r;for(int i = 1; i <= r; ++i)for(int j = 1; j <= i; ++j)cin>>a[i][j];sumMx[1][1] = a[1][1];for(int i = 2; i <= r; ++i)for(int j = 1; j <= i; ++j){sumMx[i][j] = max(sumMx[i-1][j-1], sumMx[i-1][j]) + a[i][j];if(i == r)//求第r行的最大值{if(sumMx[i][j] > mxVal)mxVal = sumMx[i][j];}}cout<<mxVal;return 0;
}

解法3:逆推法

设数组sumMx[i][j]表示从底层某位置到i,j的最大加和。
从底层向上层递推。

#include<bits/stdc++.h>
using namespace std;
#define N 1005
int a[N][N], r;//a:原始数据,r:行数
int sumMx[N][N];//sumMx[i][j]:记录从底层到i,j位置的最大加和
int mxVal;//最大加和
int main()
{cin>>r;for(int i = 1; i <= r; ++i)for(int j = 1; j <= i; ++j)cin>>a[i][j];for(int i = 1; i <= r; ++i)//底层到底层的和,即为该位置的值sumMx[r][i] = a[r][i];for(int i = r - 1; i >= 1; --i)//从倒数第二行遍历到第1行for(int j = 1; j <= i; ++j)sumMx[i][j] = max(sumMx[i+1][j], sumMx[i+1][j+1]) + a[i][j];//i,j位置的加和为其下面两个位置的加和中的最大值加上本位置的值cout<<sumMx[1][1];//底层某位置到1,1的最大加和,即为要求的值return 0;
}

信息学奥赛一本通 1258:【例9.2】数字金字塔相关推荐

  1. 信息学奥赛一本通1258:数字金字塔

    题目 信息学奥赛一本通(C++版)在线评测系统 思路 这一道题大家可以自己先在纸上画一画,不出意外的话,你的答案应该是这样的 算出来答案是63,然而!有一个更优的答案!! 结果是86! 这是为啥嘞?因 ...

  2. 信息学奥赛一本通1258:【例9.2】数字金字塔题解

    [题目表述] [考点分析] 动态规划 [解题思路] 样例金字塔可以看成下面的形式方便使用数组来处理: 13 11  8 12  7    26 6   14  15    8 12  7   13  ...

  3. 信息学奥赛一本通(1239:统计数字)

    1239:统计数字 时间限制: 1000 ms         内存限制: 65536 KB 提交数: 6439     通过数: 2627 [题目描述] 某次科研调查时得到了n个自然数,每个数均不超 ...

  4. 信息学奥赛一本通C++语言——1096:数字统计

    [题目描述] 请统计某个给定范围[L,R]的所有整数中,数字 2 出现的次数. 比如给定范围[2,22],数字2在数2中出现了1次,在数12中出现1次,在数20中出现1次,在数21中出现1次,在数22 ...

  5. 信息学奥赛一本通 1102:与指定数字相同的数的个数 | OpenJudge NOI 1.6 01

    [题目链接] ybt 1102:与指定数字相同的数的个数 OpenJudge NOI 1.6 01:与指定数字相同的数的个数 [题目考点] 1.一维数组 2. 计数 [题解代码] 解法1: #incl ...

  6. 信息学奥赛一本通 1068:与指定数字相同的数的个数 | OpenJudge NOI 1.5 12

    [题目链接] ybt 1068:与指定数字相同的数的个数 OpenJudge NOI 1.5 12:与指定数字相同的数的个数 [题目考点] 1. 循环统计 [题解代码] 解法1:用if语句 #incl ...

  7. 信息学奥赛一本通 2021:【例4.6】最大公约数

    [题目链接] ybt 2021:[例4.6]最大公约数 [题目考点] 1. while循环 2. 求最大公约数 辗转相减法 辗转相除法 [解题思路] 解法1:枚举 取较小数字,从该数字的值开始从大到小 ...

  8. 信息学奥赛一本通 1278:【例9.22】复制书稿(book) | 洛谷 P1281 书的复制

    [题目链接] ybt 1278:[例9.22]复制书稿(book) 洛谷 P1281 书的复制 [题目考点] 1. 动态规划:线性动规 [解题思路] 该题可以抽象为:将由m个数字构成的序列分成k个子段 ...

  9. 【例1】 0/1背包《信息学奥赛一本通》【解法一】 02

    /* [例1] 0/1背包<信息学奥赛一本通>[解法一] 02 http://ybt.ssoier.cn:8088/problem_show.php?pid=1267 */ #includ ...

最新文章

  1. Oracle 用Drapper进行like模糊传参查询需要在参数值前后带%符合
  2. python 爬虫工具
  3. Knative 应用在阿里云容器服务上的最佳实践
  4. 计算机设备投标标书范本,OA办公自动化系统投标文件(标书范本)
  5. Quartz框架应用(1)
  6. 在线JSON转Mongoose工具
  7. php 添加表,关于php:如何向MYSQL表添加新列
  8. 21.Linux/Unix 系统编程手册(上) -- 信号:信号处理器函数
  9. 树莓派安装rtl8192eu无线网卡驱动
  10. signature=461282e191fe3d72a8b43e5b831644fb,Proposed Graphene Nanospaser
  11. win7系统调整屏幕刷新率方法
  12. 智能家居更智能,小程序的生态合作新方案
  13. 几个简单的论文下载方法
  14. 孙鑫VC++深入详解第三章学习笔记
  15. #每天一道算法题:出现一次与出现k次的数
  16. file和folder的区别是什么?
  17. 2019年度区块链安全复盘总结
  18. Mr.Fang出品:银企互联(NC模式)开发者版本(.NET WebService中间件,Java、PHP、Python等跨语言测试通过)
  19. 喜报 | 360安全云盘入选《中国云盘行业专题分析2021》优秀案例
  20. ovs实现的几种openflow扩展消息

热门文章

  1. 玩玩IronPython
  2. [转]这才是真正的3D显示!Leap Motion推出次毫米级3D手动控制技术,让人手和影像融为一体...
  3. C# ref与out区别
  4. 微服务治理框架的选择:对比Spring Cloud和Istio
  5. Keras入门必读教程:手把手从安装到解决实际问题
  6. 同事说他的应用起不来了,因为我的代码里面多了一个空格!
  7. 老板:再用Log4j就收拾东西回家吧!
  8. 还看不懂同事的代码?Lambda 表达式、函数接口了解一下
  9. 数字化转型下的银行云单元架构
  10. JEECG开源说明:JEECG 完全开源,不收任何费用,可以任用于商业!