1.问题描述
如图所示,所谓数字三角形问题,即根据一棵完全二叉树从其根结点开始寻找一条其到叶子结点的路径,使得路径上所经过的数字之和最小(也有的求最大值)。很多算法题目的原型就是这个问题,比如:http://hihocoder.com/problemset/problem/1037。
2.算法思路
解决这个问题,最经典的还是利用动态规划。
3.实现代码
#include<iostream>
using namespace std;
int main(){
int n=0;
cin>>n;
int* x=new int[n];
int* best=new int[n];
for(int i=0;i<n;++i){
x[i]=0;
best[i]=0;
}
for(int i=0;i<n;++i){
for(int j=0;j<=i;++j){//每次输入一行
cin>>x[j];
}
//这里从右向左(j=i,...,0)计算是为了将空间复杂度减少到O(n),如果从左到右计算的话空间复杂度为 //O(n^2).这个其实在利用动态规划解决问题中减少空间复杂度的一个简单技巧.
for(int j=i;j>=0;--j){
if(0==j){//最左结点
best[j]=best[j]+x[j];
}else if(i==j){//最右结点
best[j]=best[j-1]+x[j];
}else{
best[j]=max(best[j-1],best[j])+x[j];
}
}
}
//从左到右遍历叶子结点,求出最优路径和
int max=0;
for(int i=0;i<n;++i){
if(max<best[i]){
max=best[i];
}
}
cout<<max<<endl;
delete []x;
delete []best;
return 0;
}
#include<iostream>
using namespace std;
int main(){
int n=0;
cin>>n;
int* x=new int[n];
int* best=new int[n];
for(int i=0;i<n;++i){
x[i]=0;
best[i]=0;
}
for(int i=0;i<n;++i){
for(int j=0;j<=i;++j){//每次输入一行
cin>>x[j];
}
//这里从右向左(j=i,...,0)计算是为了将空间复杂度减少到O(n),如果从左到右计算的话空间复杂度为 //O(n^2).这个其实在利用动态规划解决问题中减少空间复杂度的一个简单技巧.
for(int j=i;j>=0;--j){
if(0==j){//最左结点
best[j]=best[j]+x[j];
}else if(i==j){//最右结点
best[j]=best[j-1]+x[j];
}else{
best[j]=max(best[j-1],best[j])+x[j];
}
}
}
//从左到右遍历叶子结点,求出最优路径和
int max=0;
for(int i=0;i<n;++i){
if(max<best[i]){
max=best[i];
}
}
cout<<max<<endl;
delete []x;
delete []best;
return 0;
}