【计算机算法】动态规划——数塔问题

动态规划解决数塔问题

题目

从一个数塔中找出一条路径,使路径上的数组和最小

代码

#include<iostream>
using namespace std;

int arr[100][100];//存储数塔的数组 
int step[100][100];//记录步数的数组,即往哪个方向走 
int calculatearr[100][100];//用于记录计算步数的数组
int layer;//层数 
int k = 1;//这是用于输出层数时判断到第几层了 

void manage(); 
void outAndNext(int x,int i,int j); 
//初始化函数 
void initialize(){
    
    //将数组中的元素全部初始化为0 
	for(int i = 0;i < 100;i ++){
    
    
		for(int j = 0;j < 100;j ++){
    
    
			arr[i][j] = 0;
			step[i][j] = 0;
			calculatearr[i][j] = 0;
		}
	}
} 
//输入函数 
void input(){
    
    
	cout<<"请输入数塔层数:";
	cin>>layer;
	for(int i = 1;i <= layer;i ++){
    
    
		for(int j = 1;j <= i;j ++){
    
    
			cin>>arr[i][j];
		}
	}
	manage();//处理数组 
	
}
//处理计算数组,使得最底层与数塔的值一致 
void manage(){
    
    
	for(int j = 1;j <= layer;j ++){
    
    
		calculatearr[layer][j] = arr[layer][j];
	}
}
//计算具体的步数 
void startToJudge(){
    
    
	for(int i = layer - 1;i > 0; i --){
    
    
		for(int j = 1;j <= i;j ++){
    
    
			calculatearr[i][j] = arr[i][j] + min(calculatearr[i + 1][j],calculatearr[i + 1][j + 1]);
			calculatearr[i + 1][j] > calculatearr[i + 1][j + 1]? (step[i][j] = 1):(step[i][j] = 0);
		}
	} 
}

//输出向左走还是向右走 
void everyStep(int i, int j){
    
    
	if(k == layer - 1){
    
    
		if(calculatearr[i][j] == 0)
			cout<<"向左"<<endl;
		else
			cout<<"向右"<<endl; 
	}
	else if(k <= layer){
    
    
		outAndNext(step[i][j],i,j);
	}
} 
void outAndNext(int x,int i,int j){
    
    
	if(x == 0){
    
    
		k++;
		cout<<"向左-->";
		everyStep(i + 1,j);
		
	}
	else{
    
    
		k++;
		cout<<"向右-->";
		everyStep(i + 1,j + 1);
	}
}
//输出数塔原型 
void outputarr(){
    
    
	for(int i = 1;i <= layer;i ++){
    
    
		for(int j = layer - i;j >= 0;j --){
    
    
			cout<<"	";
		}
		for(int z = 1;z <= i;z++){
    
    
			cout<<arr[i][z]<<"		";
		}
		cout<<endl;
	}	
}

int main(){
    
    
	initialize();//初始化数组 
	input();//输入函数 
	startToJudge();//开始判断 
	outputarr();//输出数塔原型 
	cout<<"该数塔的最小值为:"<<calculatearr[1][1]<<endl;
	cout<<"走法为:";
	everyStep(1,1);
	
}

运行截图

在这里插入图片描述
调用outputarr()用来输出数塔原本的样子
调用startToJudge()来计算并填充calculatearr数组,在这个数组的[1][1]为最优解(即数塔最短的一条路径)
everystep()用来输出向哪个方向走,主要是根据step[][]数组进行判断,从而输出

求数塔最大值

只需要修改startToJudge()函数的其中两句(第二个for循环中的)

calculatearr[i][j] = arr[i][j] + max(calculatearr[i + 1][j],calculatearr[i + 1][j + 1]);
calculatearr[i + 1][j] > calculatearr[i + 1][j + 1]? (step[i][j] = 0):(step[i][j] = 1);

猜你喜欢

转载自blog.csdn.net/passer__jw767/article/details/112076944
今日推荐