动态规划-数字三角形

此题目来源于北大POJ,在下面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或 右下走。只需要求出这个最大和即可,不必给出具体路径。 三角形的行数大于1小于等于100,数字为 0 - 99

7

 3 8 

 8 1 0

 2 7 4 4

  4 5 2 6 5

/*思路1:有题目可知,每个tri(i, j)只和它的左上以及右上相关,tri(i-1, j-1)和tri(i-1. j),假定我们知道走到tri(i-1, j-1)和tri(i-1. j)的数字和,那么tri(i, j)的数字和就为max(tri(i-1, j-1), tri(i-1, j-) + tri(i, j),由此我们可以计算出整个三角形所有的点数字和,最后取最后一行中最大的值作为结果输出。

思路2:我们换个角度,前一个思路是正规的自上而下,如果我们从下而上做可以吗?我们以最后一行为基础,那么它的上一行各个点的数字和是则是这一行max(tri(i, j), tri(i,j+1)) +tri(i-1, j),依次从下而上求解整个三角形,最终顶点就为最大的值,作为结果输出

思路3:作为递归求解,因为它是重复求解每个点的数字和,直到达到最后一行,停止递归,输出最后结果,但是递归的缺点也很明显,因为重复计算导致时间开销非常大,所以这个思路在对时间复杂度有要求的情况下,不适合*/

//思路1:

#include <iostream>
#include <vector>
#include <string>
#include <sstream>

using namespace std;


int maxSum(vector<vector<int>> matrix, int triLine){
	if (triLine < 1){
		return 0;
	}
	//初始化最左列和最右列,因为他们的值仅取决单个对象,无需比较
	for (int i = 1; i < triLine; i++){
		matrix[i][0] += matrix[i - 1][0];
		matrix[i][i] += matrix[i - 1][i - 1];
	}

	for (int i = 2; i < triLine; i++){
		for (int j = 1; j < i ; j++){
			if (matrix[i-1][j-1] < matrix[i-1][j]){
				matrix[i][j] += matrix[i - 1][j];
			} 
			else{
				matrix[i][j] += matrix[i - 1][j -1];
			}
		}
	}
	int maxNum = 0;
	for (int i = 0; i < triLine; i++){
		if (matrix[triLine -1][i] > maxNum){
			maxNum = matrix[triLine - 1][i];
		}
	}
	return maxNum;
}


int main(int argc, char **argv)
{
	vector<vector<int>> matrix;
	int triLine = 0;
	string Line; stringstream ss;
	getline(cin, Line);
	ss << Line; ss >> triLine;
	//matrix.resize(triLine);

	for (int i = 0; i < triLine; i++){
		vector <int> vi;
		vi.resize(i + 1);
		string s =""; 
		getline(cin, s);
		ss.clear(); ss.str(""); ss << s;
		for (int j = 0; j < i + 1; j++){
			ss >> vi[j];
		}
		matrix.push_back(vi);
	}

	cout << maxSum(matrix, triLine);

	return 0;
}
//思路2:

int maxSum(vector<vector<int>> matrix, int triLine){
	if (triLine < 1){
		return 0;
	}
	for (int i = triLine - 2; i >= 0; i--){
		for (int j = 0; j < i + 1; j++){
			if (matrix[i+1][j] > matrix[i+1][j+1]){
				matrix[i][j] += matrix[i + 1][j];
			}
			else{
				matrix[i][j] += matrix[i + 1][j + 1];
			}
		}
	}
	return matrix[0][0];
}
递归实现的主体如下:

if(num = n)

return matrix[i][j];

else

maxtrix[i][j] = maxSum(max(matrix[i+1][j], matrix[i+1][j+1]) + matrix[i][j]);

动态规划个人感觉涉及到矩阵最优的编程题,差不多都可以考虑用动态规划解决,动态规划是将问题的所有解求出来,然后选出最优值,这区别于贪心算法,贪心是在每步找个最优值,再走下一步。

猜你喜欢

转载自blog.csdn.net/S_powerStone/article/details/75084177