数塔问题:
问题描述:
将一些数字排成数塔现状,期中第n层又n个数
每次只能向下一层连接的数字中的一个
问:将路径上所有数字相加后得到的最大和是多少
样例1:
输入:
5
5
8 3
12 7 16
4 10 11 6
9 5 3 9 4
输出:
44
样例一图如下:
样例2:
输入:
5
9
12 15
10 6 8
2 18 9 5
19 7 10 4 16
输出:
59
本题可直接采用递归手段,暴力穷举所有的情况并在同时比较最大值
#include
using namespace std;
int num=0;//全局变量
int MaxSum=0;//全局变量
void GetMaxSum(int **arr,int i,int j,int sum){//i,j表示现在进行的(行-1)和(列-1)
(MaxSum>sum)? :MaxSum=sum;//刷新最大值
if(i<num){
GetMaxSum(arr,i+1,j,sum+arr[i][j]); //往靠左下连接处做加法
GetMaxSum(arr,i+1,j+1,sum+arr[i][j]);//往靠右下连接处做加法
}
}
int main(){
cin>>num;
int **arr; //定义二维指针 (可用数组代替)
arr=new int*[num];//动态分配空间
for(int i=0;i<num;i++){
arr[i]=new int[num];
}
for(int i=0;i<num;i++){//数据读入
for(int j=0;j<=i;j++){
cin>>arr[i][j];
}
}
GetMaxSum(arr,0,0,0);//函数调用
cout<<MaxSum;
for(int i=0;i<num;i++){//先删除一维指针,再删除二维指针
delete[]arr[i];
}
delete []arr;
return 0;
}
因为每层中数字有两个分支,因此时间复杂度为O(2^n),在n很大情况下无法接受,加上我要描述的是动态规划的思路,所以:
但采用自底而上的思路:每一次都是靠左下和靠右下的值中大者加上该位置的值,最后只需要给出第一层的值即可
即arr[n-1][i]=MAX(arr[n][i],arr[n][i+1])+arr[n-1][i] ;
#include
using namespace std;
int MAX(int a,int b){//MAX函数求最大值
if(a>b){
return a;
}
else{
return b;
}
}
int GetMaxSum(int **arr,int n){//n表示当前进行层数 (从第num-1到0阶)
if(n==0){//终止条件
return arr[0][0];
}
else{
for(int i=0;i<n;i++){
arr[n-1][i]+=MAX(arr[n][i],arr[n][i+1]); //下一层数据中的大值加上该数据
}
GetMaxSum(arr,n-1);//遍历所有层
}
}
int main(){
int num;
cin>>num;
int **arr; //定义二维指针
arr=new int*[num];//动态分配空间
for(int i=0;i<num;i++){
arr[i]=new int[num];
}
for(int i=0;i<num;i++){//数据读入
for(int j=0;j<=i;j++){
cin>>arr[i][j];
}
}
cout<<GetMaxSum(arr,num-1);//函数调用
for(int i=0;i<num;i++){//先删除一维指针,再删除二维指针
delete[]arr[i];
}
delete []arr;
return 0;
}
若有不妥,请指正,谢。