poj1163 dp入门题 数塔
2015-08-05 01:24
288 查看
数塔问题:给你一个数字三角形, 形式如下:
5 //三角形行数。下面是三角形
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
找出从第一层到最后一层的一条路,使得所经过的权值之和者最大。
路径上的每一步都只能往左下或右下走。三角形的行数大于1小于等于100。
问题解决思路:用递推型的dp解题,有自底向上的”人人为我“与 自顶向下的“我为人人”。
自底向上的思路是从底部向上逐级递推求出最终结果
状态dp[i][j]表示i行j列到底层所经过的权值之和的最大值
状态转移方程为:dp[i][j]=max(dp[i+1][j],dp[i+1][j])+a[i][j];
最终输出结果即为dp[0][0]
源代码:
由于dp[i][j]只与dp[i+1][j]及dp[i+1][j+1]有关,在每次状态转移之后第i+1行的数据就不再需要,所以可以只用一个一维数组dp[j]表示当前行各列到底层的权值和最大的路径的权值和。进而发现可以不用再开数组,直接用二维数组a即可满足状态转移过程中对内存的需求.
状态转移方程:a[i][j]=max(a[i+1][j],a[i+1][j+1])+a[i][j];
输出a[0][0];
源代码:
自顶到下的思路是从顶端向下逐步更新状态来求得最优解。
状态dp[i][j]表示从i行j列到底层的最优解;
状态转移方程:dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+a[i][j];
最后的结果为底层数字的最大值。
优化好空间后的源代码:
5 //三角形行数。下面是三角形
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
找出从第一层到最后一层的一条路,使得所经过的权值之和者最大。
路径上的每一步都只能往左下或右下走。三角形的行数大于1小于等于100。
问题解决思路:用递推型的dp解题,有自底向上的”人人为我“与 自顶向下的“我为人人”。
自底向上的思路是从底部向上逐级递推求出最终结果
状态dp[i][j]表示i行j列到底层所经过的权值之和的最大值
状态转移方程为:dp[i][j]=max(dp[i+1][j],dp[i+1][j])+a[i][j];
最终输出结果即为dp[0][0]
源代码:
[code]#include<iostream> using namespace std; int a[105][105]; int dp[105][105]; int main(){ int n; while(cin>>n){ for(int i=0;i<n;i++) for(int j=0;j<=i;j++) cin>>a[i][j]; for(int i=n-1;i>=0;i--) for(int j=0;j<=i;j++) if(i==n-1) dp[i][j]=a[i][j]; else dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+a[i][j]; cout<<dp[0][0]<<endl; } return 0; }
由于dp[i][j]只与dp[i+1][j]及dp[i+1][j+1]有关,在每次状态转移之后第i+1行的数据就不再需要,所以可以只用一个一维数组dp[j]表示当前行各列到底层的权值和最大的路径的权值和。进而发现可以不用再开数组,直接用二维数组a即可满足状态转移过程中对内存的需求.
状态转移方程:a[i][j]=max(a[i+1][j],a[i+1][j+1])+a[i][j];
输出a[0][0];
源代码:
[code]#include<iostream> using namespace std; int a[105][105]; int main(){ int n; while(cin>>n){ for(int i=0;i<n;i++) for(int j=0;j<=i;j++) cin>>a[i][j]; for(int i=n-2;i>=0;i--) for(int j=0;j<=i;j++) a[i][j]=max(a[i+1][j],a[i+1][j+1])+a[i][j]; cout<<a[0][0]<<endl; } return 0; }
自顶到下的思路是从顶端向下逐步更新状态来求得最优解。
状态dp[i][j]表示从i行j列到底层的最优解;
状态转移方程:dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+a[i][j];
最后的结果为底层数字的最大值。
优化好空间后的源代码:
[code]#include<iostream> #include<algorithm> using namespace std; int a[105][105]; int main(){ int n; while(cin>>n){ for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) cin>>a[i][j]; for(int i=2;i<=n;i++) for(int j=0;j<i;j++) a[i][j]=max(a[i-1][j],a[i-1][j-1])+a[i][j]; cout<<*max_element(a ,a +n+1)<<endl;//求数组中的最大值 } return 0; }
相关文章推荐
- Direct-X学习笔记--三维粒子系统
- 用链表实现id,姓名,分数的录入功能和排序功能
- Retrieving a List of Contacts
- Sigma Function
- Android双击返回键退出APP
- 网页控制LED (写通道形式)
- RYU安装与遇见的错误
- 黑马程序员-ios学习笔记 Foundation 中的 NSFileManager
- 关于int,String,char的一道面试题
- [UVA1619]Feel Good[DP]
- #每日Linux小练习#02 tr命令的使用
- jQuery 仿百度输入标签插件
- HDU 2844
- 位置式PID算法的C语言代码
- 停止,启动job
- 线程安全的观察者模式的设计
- Windows7 sp1 64位下安装配置eclipse+jdk+CDT+minGW
- 我的个人简历
- 首页-1
- Java中String的equals和==