(转)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];
}
#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;
}