Standard IO-----数字金字塔(CCF 1145)
来源:互联网 发布:windows专业版和旗舰版 编辑:程序博客网 时间:2024/05/29 03:43
数字金字塔
题目描述
观察下面的数字金字塔。写一个程序查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以从当前点走到下方的点也可以到达右下方的点。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
在上面的样例中,从7到3到8到7到5的路径产生了最大的和30。
输入
第一个行包含R(1<= R<=1000),表示行的数目。
后面每行为这个数字金字塔特定行包含的整数。
所有的被供应的整数是非负的且不大于100。
输出
单独的一行,包含那个可能得到的最大的和。
样例输入
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
样例输出
30
数据范围限制
1<= R<=1000
做题地址:CCF中学生程序设计在线评测系统-1145. 数字金字塔 (需要注册)
这是一道简单,经典的DP题目。
如果刚开始入手DP没有思路的话,可以先从搜索的角度想(ˇˍˇ)~
搜索思路
题目要求输出最大和,可以使用深搜把每种情况枚举出来求和,找出最大值。
1<=R<=1000
看这数据范围,TLE,妥妥的。
#include<cstdio>#include<algorithm>using namespace std;int best,a[1005][1005],n;void dfs(int x,int y,int sum){ if(x>n) { best=max(best,sum); return ; } dfs(x+1,y,sum+a[x+1][y]); dfs(x+1,y+1,sum+a[x+1][y+1]);}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) scanf("%d",&a[i][j]); dfs(1,1,a[1][1]); printf("%d\n",best);}/* Language: C++ Result: 时间超限 Time:2004 ms Memory:4976 kb*/
既然普通的深搜不行,那试试记忆化搜索吧!把走到当前的最大值记录下来,再遇到时直接比较。
还是TLE……
#include<cstdio>#include<algorithm>#include<iostream>using namespace std;int a[1005][1005],f[1005][1005],ans,n;int F(int x,int y){ if(f[x][y]) return f[x][y]; if(x==1 && y==1) return f[1][1]=a[1][1]; if(x==y) return f[x][y]=a[x][y]+F(x-1,y-1); if(y==1) return f[x][y]=a[x][y]+F(x-1,y); return f[x][y]=a[x][y]+max(F(x-1,y-1),F(x-1,y));}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) scanf("%d",&a[i][j]); for(int i=1;i<=n;i++) ans=max(F(n,i),ans); printf("%d\n",ans);}/* Language: C++ Result: 时间超限 Time:1998 ms Memory:9392 kb*/
唉╮(╯▽╰)╭
DP隆重登场
DP中有两个很重要的概念:
状态——对于一个多阶段问题,描述在一系列阶段后所处的一个状况
转移——将复杂状态转为简单状态
知道了这些,就可以愉快的码DP了
~\(≧▽≦)/~
DP代码
#include<cstdio>#include<algorithm>#include<iostream>using namespace std;int a[1005][1005],f[1005][1005],ans,n;void F(){ for(int i=2;i<=n;i++) for(int j=1;j<=i;j++) { if(j==1) f[i][j]=f[i-1][j]+a[i][j]; else if(j==i) f[i][j]=a[i][j]+f[i-1][j-1]; else f[i][j]=max(f[i-1][j-1],f[i-1][j])+a[i][j]; }}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) scanf("%d",&a[i][j]); f[1][1]=a[1][1]; F(); for(int i=1;i<=n;i++) ans=max(f[n][i],ans); printf("%d\n",ans);}/* Language: C++ Result: 正确 Time:95 ms Memory:9392 kb*/
IN THE END
上面两段TLE代码,除了凑字数(凑字咋地),还有重要的一点:
使用搜索的思路看DP题可以避免千篇一律的套公式。
阅读全文
0 0
- Standard IO-----数字金字塔(CCF 1145)
- Standard IO---产生数(CCF 1126)
- CCF NOI1145 数字金字塔【DP】
- Standard IO-----数的划分问题(三)(CCF 1187)
- 数字游戏 (Standard IO)
- NOI-CCF 1123. A-B (Standard IO)
- 2032. 数字游戏 (Standard IO)
- 2032. 数字游戏 (Standard IO)
- Standard IO-----数的划分问题(一)(CCF 1185)
- Standard IO-----数的划分问题(二)(CCF 1186)
- 字母金字塔(类同数字金字塔)
- 数字金字塔(动态规划)
- 数字金字塔(动态规划)
- 数字金字塔(逆推)
- 数字金字塔(动态规划)
- 数字金字塔(动态规划)
- 数字金字塔
- 数字金字塔
- unity3d各种OpenFileDialog操作
- 动态规划问题总结
- SQL聚合函数--JDBC(Java DataBase Connection)
- Glide最新版V4使用指南
- 对数字图像的理解(一)
- Standard IO-----数字金字塔(CCF 1145)
- Python_uuid
- Hibernate--hibernate.cfg.xml说明
- Jetty 的工作原理以及与 Tomcat 的比较
- C++ revisit
- 172. Factorial Trailing Zeroes计算n!末尾0的个数
- python3 [爬虫入门实战]爬虫之selenium 安装设置与初步使用
- Nginx全局变量
- C# 连接数据库 以及数据库增删改查