算法1:递归
设 f(i, j) 是从(i, j)点出发向下走的最长路径。
f(i, j) = max( f(i+1, j), f(i+1, j+1) ).
输出f(0, 0).
code:
#
include <iostream.h>
# define MAX 101
int triangle[ MAX ][ MAX ];
int n;
int longestPath(int i , int j);
void main(){
int i , j;
cin >> n;
for (i = 0 ;i < n;i ++ )
for (j = 0 ;j <= i;j ++ )
cin >> triangle[i][j];
cout << longestPath( 0 , 0 ) << endl;
}
int longestPath(int i , int j){
if (i == n)
return 0 ;
int x = longestPath(i + 1 , j);
int y = longestPath(i + 1 , j + 1 );
if (x < y)
x = y;
return x + triangle[i][j];
}
# define MAX 101
int triangle[ MAX ][ MAX ];
int n;
int longestPath(int i , int j);
void main(){
int i , j;
cin >> n;
for (i = 0 ;i < n;i ++ )
for (j = 0 ;j <= i;j ++ )
cin >> triangle[i][j];
cout << longestPath( 0 , 0 ) << endl;
}
int longestPath(int i , int j){
if (i == n)
return 0 ;
int x = longestPath(i + 1 , j);
int y = longestPath(i + 1 , j + 1 );
if (x < y)
x = y;
return x + triangle[i][j];
}
超时!!!
原因:大量重复计算
f(0, 0) = max( f(1, 0), f(1, 1) ).
f(1, 0) = max( f(2, 0), f(2, 1) ).
f(1, 1) = max( f(2, 1), f(2, 2) ).
f(2, 0) = max( f(3, 0), f(3, 1) ).
f(2, 1) = max( f(3, 1), f(3, 2) ).
f(2, 2) = max( f(3, 1), f(3, 2) ).
。
。
。
f(4, 0) = max( f(5, 0), f(5, 1) ).
。
。
算法2:动态规划
一般的转化方法:
原来递归函数有几个参数,就定义一个几维的数组,数组的下标是递归函数参数的取值范围,数组元素的值是递归函数的返回值,这样就可以从边界开始,逐步填充数组,相当于计算递归函数值的逆过程。
code:
#
include<stdio.h>
# define MAX 100
int triangle[ MAX ][ MAX ];
int main()
{
int n , i , j;
scanf( " %d " , & n);
for (i = 0 ; i < n; i ++ )
for (j = 0 ; j <= i; j ++ )
scanf( " %d " , triangle[i] + j);
for (i = n - 2 ; i >= 0 ; i -- )
for (j = 0 ; j <= i; j ++ )
triangle[i][j] += triangle[i + 1 ][j] > triangle[i + 1 ][j + 1 ] ? triangle[i + 1 ][j] : triangle[i + 1 ][j + 1 ];
printf ( " %d\n " , triangle[ 0 ][ 0 ]);
return 0 ;
}
# define MAX 100
int triangle[ MAX ][ MAX ];
int main()
{
int n , i , j;
scanf( " %d " , & n);
for (i = 0 ; i < n; i ++ )
for (j = 0 ; j <= i; j ++ )
scanf( " %d " , triangle[i] + j);
for (i = n - 2 ; i >= 0 ; i -- )
for (j = 0 ; j <= i; j ++ )
triangle[i][j] += triangle[i + 1 ][j] > triangle[i + 1 ][j + 1 ] ? triangle[i + 1 ][j] : triangle[i + 1 ][j + 1 ];
printf ( " %d\n " , triangle[ 0 ][ 0 ]);
return 0 ;
}