原题:Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[2],
[3,4],
[6,5,7],
[4,1,8,3]
The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).
Note:Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.
相似修改:Number Triangle
Time limit: 1 second Memory limit: 64MB
Problem Description
Consider the number triangle shown below. Write a program that calculates the highest sum of numbers that can be passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
In the sample above, the route from 7 to 3 to 8 to 7 to 5 produces the highest sum: 30.
Input Description
There are multiple test cases. The first line of each test case contains R (1 <= R <= 1000), the number of rows. Each subsequent line contains the integers for that particular row of the triangle. All the supplied integers are non-negative and no larger than 100.
Output Description
Print a single line containing the largest sum using the traversal specified for each test case.
Sample Input
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
Sample Output
30
下面给出原题的解法:
解法一:从上往下遍历,时间复杂度为O(n^2),且需要处理每行的头和尾
1 class Solution { 2 public: 3 int minimumTotal(vector<vector<int> > &triangle) { 4 vector<vector<int>> temp(triangle); 5 vector<vector<int>>::size_type length=temp.size(); 6 int i,j; 7 for(i=1;i<length;i++){ 8 vector<int>::size_type length_inner = temp[i].size(); 9 for(j=0;j<length_inner;j++){ 10 if(j == 0){ 11 temp[i][j] = temp[i][j] + temp[i-1][j]; 12 }else if(j == length_inner - 1){ 13 temp[i][j] = temp[i][j] + temp[i-1][j-1]; 14 }else{ 15 temp[i][j] = (temp[i][j] + temp[i-1][j-1] < temp[i][j] + temp[i-1][j] ? temp[i][j] + temp[i-1][j-1]:temp[i][j] + temp[i-1][j]); //求和最大的路径即'<'改成'>' 16 } 17 } 18 } 19 int min = temp[length-1][0]; 20 for(i=1;i<temp[length-1].size();i++){ 21 min = (min < temp[length-1][i]?min:temp[length-1][i]); //求和最大的仅做相应简单修改 22 } 23 return min; 24 } 25 };
解法二:从下往上遍历,从倒数第二行开始计算每个元素与下一行与它相邻的两个元素的和,比较并保存最小值,最后triangle[0][0]即为结果
#include<iostream> #include<vector> using namespace std; int maxmumTotal(vector<vector<int>> &triangle) { vector<vector<int>> temp(triangle); for(int i=temp.size()-2;i>=0;i--) { for(int j=0;j<temp[i].size();j++) { temp[i][j]+=min(temp[i+1][j],temp[i+1][j+1]); } } return temp[0][0]; } int main() { int n = 0; while (cin >> n) { vector<vector<int>> tree; for (int i = 0; i < n; ++i) { vector<int> row; for (int j = 0; j <= i; ++j) { int temp = 0; cin >> temp; row.push_back(temp); } tree.push_back(row); } cout<<maxmumTotal(tree); } system("pause"); }