动态规划--三角数塔问题

1、 三角数塔问题

设有一个三角形的数塔,顶点为根结点,每个结点有一个整数值。从顶点出发,可以向左走或向右走,如图所示:

 

要求从根结点开始,请找出一条路径,使路径之和最大,只要输出路径的和。

解题思路:

设状态为 f (i; j ),表示从从位置 (i; j ) 出发,路径的最大和,则状态转移方程为

f(i,j)=max{f(i+1,j),f(i+1,j+1)}+(i,j)

#include <iostream>
#include <algorithm>

using namespace std;

/************************************************************************/
/* 数塔问题                                                               */
/************************************************************************/
const int N = 50;//为了算法写起来简单,这里定义一个足够大的数用来存储数据(为了避免运算过程中动态申请空间,这样的话算法看起来比较麻烦,这里只是为了算法看起来简单)
int data[N][N];//存储数塔原始数据
int dp[N][N];//存储动态规划过程中的数据
int n;//塔的层数

/*动态规划实现数塔求解*/
void tower_walk()
{
    // dp初始化
    for (int i = 0; i < n; ++i)
    {
        dp[n - 1][i] = data[n - 1][i];
    }
    int temp_max;
    for (int i = n - 1; i >= 0; --i)
    {
        for (int j = 0; j <= i; ++j)
        {
            // 使用递推公式计算dp的值
            temp_max = max(dp[i + 1][j], dp[i + 1][j + 1]);
            dp[i][j] = temp_max + data[i][j];
        }
    }
}

/*打印最终结果*/
void print_result()
{
    cout << "最大路径和:" << dp[0][0] << '\n';
    int node_value;
    // 首先输出塔顶元素
    cout << "最大路径:" << data[0][0];
    int j = 0;
    for (int i = 1; i < n; ++i)
    {
        node_value = dp[i - 1][j] - data[i - 1][j];
        /* 如果node_value == dp[i][j]则说明下一步应该是data[i][j];如果node_value == dp[i][j + 1]则说明下一步应该是data[i][j + 1]*/
        if (node_value == dp[i][j + 1]) ++j;
        cout << "->" << data[i][j];
    }
    cout << endl;
}

int main()
{
    cout << "输入塔的层数:";
    cin >> n;
    cout << "输入塔的节点数据(第i层有i个节点):\n";
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j <= i; ++j)
        {
            cin >> data[i][j];
        }
    }

    tower_walk();
    print_result();
}

类似的问题还有:

1.三角形找一条从顶到底的最小路径

设状态为 f(i; j ),表示从从位置 (i; j ) 出发,路径的最小和,则状态转移方程为

f(i,j)=min{f(i+1,j),f(i+1,j+1)}+(i,j)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值