标签:深度遍历 include targe 简单的 either write sed std org
题目链接:http://poj.org/problem?id=1163
Description
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
(Figure 1)
Input
Output
Sample Input
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
Sample Output
30
题意:在上面的数字三角形中寻找一条从顶部到底边的路径,使得 路径上所经过的数字之和最大。路径上的每一步都只能往左下或 右下走。只需要求出这个最大和即可,不必给出具体路径。三角形的行数大于1小于等于100,数字为 0 - 99
解题思路:我们可以用二维数组存放数字三角形。map( i, j) : 第i行第 j 个数字(i,j从1开始算).它是一个典型的递归问题。 map(i, j)出发,下一步只能走map(i+1,j)或者D(i+1, j+1)。但是如果采用递规的方法,深度遍历每条路径,存在大 量重复计算。则时间复杂度为 2^n,对于 n = 100 行,肯定超时。这里我们可以采用两种方法,第一种是采用记忆搜索的方法,如果每算出一个数组就保存起来,下次用 到其值的时候直接取用,则可免去重复计算。第二种是我们可以从下往上看,因为从顶边到底边的路径是和从底边到顶边的路径是一样的。我们把从第n行到第i行第j列位置的最大数字和设为dp[i][j],它肯定是由第i+1行的第j列的数字和或者第i+1行第j+1列加上一个map[i][j]得得到的,根据动态规划的思想,我们应该去两者中更大的那个解即最优解,于是我们就能得到递推公式:dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+map[i][j],这样我们通过从最底层一步一步向上递推就很简单了,而我们要求的答案也正是最顶层的最优解即dp[1][1].
附上代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<string.h> 4 using namespace std; 5 int n; 6 int map[105][105]; 7 int dp[105][105]; 8 9 int main() 10 { 11 cin>>n; 12 for(int i=1;i<=n;i++){ 13 for(int j=1;j<=i;j++){ 14 cin>>map[i][j]; 15 } 16 } 17 memset(dp,0,sizeof(dp)); 18 for(int i=n;i>0;i--) 19 { 20 for(int j=1;j<=i;j++) 21 { 22 dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+map[i][j]; 23 } 24 } 25 cout<<dp[1][1]<<endl; 26 return 0; 27 }
标签:深度遍历 include targe 简单的 either write sed std org
原文地址:https://www.cnblogs.com/zjl192628928/p/9321022.html