(转)POJ 1163 The Triangle 解题报告

算法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];
}

超时!!!

原因:大量重复计算

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;
}
posted @ 2010-07-14 12:27  六不朽  阅读(441)  评论(0编辑  收藏  举报