您的位置:首页 > 其它

动态规划-数字三角形

2017-07-13 16:57 134 查看
此题目来源于北大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]);
动态规划个人感觉涉及到矩阵最优的编程题,差不多都可以考虑用动态规划解决,动态规划是将问题的所有解求出来,然后选出最优值,这区别于贪心算法,贪心是在每步找个最优值,再走下一步。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: