动态规划之数塔问题

  1. 教材习题6第1题。

有数字三角形如下:

找出从第一层到最后一层的一条路,使得所经过的权值之和最小或者最大。

#include<iostream>
using namespace std;

const int N=50;

int main()
{
	cout << "Please input N(lines): " ;
	//数塔的层数
	int n;
	cin >> n;
 
	int d[N+1][N+1][3];	//[1]用来存数,[2]参与运算,[3]表示向左(0),还是向右(1)
	//输入数塔
	for(int i = 1; i <= n; ++i)
	{
		cout << "Please input line"<< i<<": ";
		for(int j = 1; j <= i; ++j)		//第i行有i个数
		{
			cin >> d[i][j][1];
			d[i][j][2] = d[i][j][1];
			d[i][j][3] = 0;
		}
	}
	cout << endl;
	for( i = n-1; i >= 1; --i)	//从倒数第二行开始
	{
		for(int j=1; j <= i; j++)
		{
			if (d[i+1][j][2] > d[i+1][j+1][2])	
			{
				d[i][j][2] += d[i+1][j][2];
				d[i][j][3] = 0;	
			}
			else	
			{
				d[i][j][2] += d[i+1][j+1][2];
				d[i][j][3] = 1;	
			}
		}
	}	
	//输出数塔
	for( i = 1; i <= n; ++i)
	{
		for(int j = 1; j <= i; ++j)
		{
			cout << d[i][j][1] << " ";
		}
		cout << endl;
	}
	cout << "Max:"<<d[1][1][2] << endl;
	//输出路径
	int j;
	for(i = 1, j = 1; i<= n; ++i)
	{
		cout << "[" << i << "," << j << "]" << " -> ";
		j += d[i][j][3];
	}
	cout << "结束"<<endl;
	return 0;
}

结果如下:

提示:

所经过的权值之和最大值为例进行说明。

行进的过程中,每次只有两种选择:向左或向右。一个有n层的数字三角形的完整路径有2n条,所以当n比较大的时候,搜索全部路径,从中找出最大值,效率较低。

采用动态规划方法实现。

d(i,j)表示从位置(i,j)出发时得到的最大值(包括位置(i,j)本身),可以写出最大值的递归方程:

扫描二维码关注公众号,回复: 3723894 查看本文章

由于递归方程中包含了重复子问题,直接采用递归方程求解, 效率较低。采用动态规划的方法,用一张二维表记录中间过程的值,可以把时间效率提高到n2。

猜你喜欢

转载自blog.csdn.net/PD137/article/details/83217091