题目:如下图是一个数塔,从顶部出发在每一个节点可以选择向左或者向右走,一直走到底层,要求找出一条路径,使得路径上的数字之和最大,及路径情况。(使用蛮力算法和动态规划算法分别实现)
#include<bits/stdc++.h>
#define MAX_SIZE 100
using namespace std;
//蛮力算法
int maxPathSumForce(int pyramid[][MAX_SIZE],int row){
if(row==1){
return pyramid[0][0];
}
int maxSum=pyramid[0][0];
for(int i=1;i<row;i++){
for(int j=0;j<i;j++){
if(j==0){
pyramid[i][j]+=pyramid[i-1][j];
}
else if(j==i){
pyramid[i][j]+=pyramid[i-1][j-1];
}else{
pyramid[i][j] += (pyramid[i - 1][j - 1] > pyramid[i - 1][j] ? pyramid[i - 1][j - 1] : pyramid[i - 1][j]);
}
if (pyramid[i][j] > maxSum) {
maxSum = pyramid[i][j];
}
}
}
return maxSum;
}
//动态规划算法
int maxPathSumDP(int pyramid[][MAX_SIZE], int rows) {
if (rows == 1) {
return pyramid[0][0];
}
for (int i = rows - 2; i >= 0; i--) {
for (int j = 0; j <= i; j++) {
pyramid[i][j] += (pyramid[i + 1][j] > pyramid[i + 1][j + 1] ? pyramid[i + 1][j] : pyramid[i + 1][j + 1]);
}
}
return pyramid[0][0];
}
signed main()
{
int pyramid[MAX_SIZE][MAX_SIZE];
int row,num;
cout<<"请输入数塔的层数:";
cin>>row;
cout<<"请输入数塔的数字(每层从左到右依次输入):"<<endl;
for(int i=0;i<row;i++){
for(int j=0;j<=i;j++){
cin>>num;
pyramid[i][j]=num;
}
}
cout<<"蛮力算法最大路径和为:"<<maxPathSumForce(pyramid,row)<<endl;
cout<<"动态规划算法最大路径和为:"<<maxPathSumDP(pyramid,row)<<endl;
}
蛮力算法的解释:
1. 首先,如果金字塔只有一行(rows == 1),则直接返回金字塔顶部的值(pyramid[0][0])。
2. 初始化最大路径和为金字塔顶部的值(maxSum = pyramid[0][0])。
3. 使用两个嵌套的循环遍历金字塔的每一行和每一列。外层循环变量i表示行数,内层循环变量j表示列数。
4. 在内层循环中,根据当前位置的行数和列数,计算当前位置的值。具体计算方式如下:
- 如果当前位置是行的开头(j == 0),则当前位置的值等于上一行同列位置的值加上当前位置的值(pyramid[i][j] += pyramid[i - 1][j])。
- 如果当前位置是行的末尾(j == i),则当前位置的值等于上一行前一列位置的值加上当前位置的值(pyramid[i][j] += pyramid[i - 1][j - 1])。
- 否则,当前位置的值等于上一行前一列位置的值和上一行同列位置的值中的较大值(pyramid[i][j] += (pyramid[i - 1][j - 1] > pyramid[i - 1][j] ? pyramid[i - 1][j - 1] : pyramid[i - 1][j]))。
5. 在内层循环中,每次更新当前位置的值后,判断当前位置的值是否大于最大路径和(maxSum)。如果是,则更新最大路径和为当前位置的值。
动态规划算法的解释:(从下到上代码更加简洁,可能性更小)
1. 首先,如果金字塔只有一行(rows == 1),则直接返回金字塔顶部的值(pyramid[0][0])。
2. 使用两个嵌套的循环从倒数第二行开始向上遍历金字塔的每一行和每一列。外层循环变量i表示行数,内层循环变量j表示列数。
3. 在内层循环中,根据当前位置的行数和列数,计算当前位置的值。具体计算方式如下:
- 当前位置的值等于当前位置的值加上 下一行同列位置和下一行下一列位置中的较大值(pyramid[i][j] += (pyramid[i + 1][j] > pyramid[i + 1][j + 1] ? pyramid[i + 1][j] : pyramid[i + 1][j + 1]))。
4. 循环结束后,金字塔顶部的值即为从顶部到底部的最大路径和。
5. 返回金字塔顶部的值。