数字三角形-动态规划

给定一个由n行数字组成的数字三角形,设计一个算法,计算出从三角形的顶至底的一条路径,使该路径所经过的数字总和最大。

示例

			7
		  3   8
		8   1   0
	  2   7   4   4
	4   5   2   6   5
	
路径只能是左斜线向下或右斜线向下
这个示例:30

对于这个问题,可以从上往下(DP)和从下往上(DP)解决

从上往下(DP)

  • 将每一个数值与左斜线向下的值相加,存到左斜线向下的位置
  • 将每一个数值与右斜线向下的值相加,存到右斜线向下的位置
  • 当一个数值有左斜向上和右斜向上时,需要比较大小,保留较大的值
  • 最后遍历最后一行,找出最大值即可
			 7
		  10   15
	    18   16   15	//数值1拥有左斜向上和右斜向上,10+1<15+1,保留16
	  20   25   20   19
	24   30  27   26   24

遍历最后一行,找出最大值30
#include <iostream>
using namespace std;

int main()
{
    int n;
    cout << "Input n :";
    cin >> n;
    int** arr = new int*[n];
    for (int i = 0; i < n; i++)
        arr[i] = new int[i + 1];
    for(int i = 0; i < n; i++)
    {
        for (int j = 0; j <= i; j++)
        {
            cin >> arr[i][j];
        }
    }
    for (int i = 1; i < n; i++)
    {
        for (int j = 0; j <= i; j++)
        {
            if (j == 0 )
                arr[i][j] = arr[i - 1][j] + arr[i][j];//边界需要特殊处理
            else if (j == i)
                arr[i][j] = arr[i - 1][j - 1] + arr[i][j];//边界需要特殊处理
            else
                arr[i][j] = arr[i - 1][j - 1] + arr[i][j] > arr[i - 1][j] + arr[i][j] ? arr[i - 1][j - 1] + arr[i][j] : arr[i - 1][j] + arr[i][j];
        }
    }
    int max = arr[n-1][0];
    for (int i = 1; i < n; i++)
    {
        max = arr[n-1][i] > max ? arr[n-1][i] : max;
    }
    cout << "MAX IS " << max;
    for (int i = 0; i < n; i++)
    {
        delete arr[i];
    }
    delete[] arr;
}

从下往上(DP)

  • 该方法与从上往下相反,只需要将相邻两个数分别与右斜向上、左斜向上相加,保留最大值
  • 最后[0][0]元素即为所求
			 30
		  23    21
	   20    13    10
	 7    12    10   10
   4    5     2    6    5

直接取用[0][0]元素30
/* C++代码 */
#include <iostream>
using namespace std;

int main()
{
    int n;
    cout << "Input n :";
    cin >> n;
    int** arr = new int*[n];
    for (int i = 0; i < n; i++)
        arr[i] = new int[i + 1];
    for(int i = 0; i < n; i++)
    {
        for (int j = 0; j <= i; j++)
        {
            cin >> arr[i][j];
        }
    }
    for(int i=n-2;i>=0;i--)
    {
        for (int j = 0; j <= i; j++)
        {
            arr[i][j] = arr[i][j] + arr[i + 1][j] > arr[i][j] + arr[i + 1][j + 1] ? arr[i][j] + arr[i + 1][j] : arr[i][j] + arr[i + 1][j + 1];
        }
    }
    cout << "MAX IS " << arr[0][0];
    for (int i = 0; i < n; i++)
    {
        delete arr[i];
    }
    delete[] arr;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值