POJ 1163 The Triangle 【简单题】

来源:互联网 发布:淘宝的安静一键宏好吗 编辑:程序博客网 时间:2024/05/19 17:23
The Triangle
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 48479 Accepted: 29308

Description

73   88   1   02   7   4   44   5   2   6   5(Figure 1)
Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers 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. 

Input

Your program is to read from standard input. The first line contains one integer N: the number of rows in the triangle. The following N lines describe the data of the triangle. The number of rows in the triangle is > 1 but <= 100. The numbers in the triangle, all integers, are between 0 and 99.

Output

Your program is to write to standard output. The highest sum is written as an integer.

Sample Input

573 88 1 0 2 7 4 44 5 2 6 5

Sample Output

30

Source

IOI 1994


题目分析:

在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。

路径上的每一步都只能往左下或右下走。只需要求出这个最大和即可,不必给出具体路径。 


解题思路: 用二维数组存放数字三角形。  

D( r, j)   : 第r行第 j 个数字(r,j从1开始算)  

MaxSum(r, j) :   从D(r,j)到底边的各条路径中, 最佳路径的数字之和。 

问题:求 MaxSum(1,1)  
典型的递归问题。       

D(r, j)出发,下一步只能走D(r+1,j)或者D(r+1, j+1)。

故对于N行的三角形:  
 if ( r == N)   

     MaxSum(r,j) = D(r,j)  

else      

    MaxSum( r, j) = Max{ MaxSum(r+1,j), MaxSum(r+1,j+1) } + D(r,j)  


弱者的代码1(纯递归):

#include <iostream>#include <cstdio>#include <algorithm>using namespace std;const int maxn = 101;int a[maxn][maxn];int n;int MaxSum(int i, int j){   if (i == n)    return a[i][j];   int x = MaxSum(i+1, j);   int y = MaxSum(i+1, j+1);   return max(x, y) + a[i][j];}int main(){    while (scanf("%d", &n) == 1 && n)    {        for (int i = 1; i <= n; i++)            for (int j = 1; j <= i; j++)               scanf("%d", &a[i][j]);        cout << MaxSum(1, 1) << endl;    }    return 0;}

弱者的代码2(记忆化搜索):

#include <iostream>#include <cstdio>using namespace std;const int maxn = 101;int a[maxn][maxn];int maxsum[maxn][maxn];int n;int MaxSum(int i, int j){    if (maxsum[i][j] != -1)        return maxsum[i][j];    if (i == n)        maxsum[i][j] = a[i][j];    else    {        int x = MaxSum(i+1, j);        int y = MaxSum(i+1, j+1);        maxsum[i][j] = max(x, y) + a[i][j];    }    return maxsum[i][j];}int main(){    int i, j;    while (scanf("%d", &n) == 1)    {        for (i = 1; i <= 5; i++)            for (j = 1; j <= i; j++)            {                scanf("%d", &a[i][j]);                maxsum[i][j] = -1;                //memset(maxsum, -1, sizeof(maxsum));            }        printf("%d\n", MaxSum(1, 1));    }    return 0;}

弱者的代码3(递推):

#include <iostream>#include <cstdio>using namespace std;const int maxn = 101;int maxsum[maxn][maxn];int a[maxn][maxn];int n;int main(){    int i, j;    while (scanf("%d", &n) == 1)    {        for (i = 1; i <= n; i++)            for (j = 1; j <= i; j++)                scanf("%d", &a[i][j]);        for (int i = 1; i <= n; i++)            maxsum[n][i] = a[n][i];        for (int i = n-1; i >= 1; i--)            for (int j = 1; j <= i; j++)                maxsum[i][j] = max(maxsum[i+1][j], maxsum[i+1][j+1]) + a[i][j];        cout << maxsum[1][1] << endl;    }    return 0;}

The end.


0 0
原创粉丝点击