POJ1163-The Triangle

Description

7
3   8
8   1   0
2   7   4   4
4   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

5
7
3 8
8 1 0 
2 7 4 4
4 5 2 6 5

Sample Output

30

很简单的一道题,直接调用递归函数去解决。

输入数据,然后输出调用的递归函数就OK了。

int main()

int main()
{
       scanf("%d",&n);
       for(int i=1;i<=n;++i)
       {
           for(int j=1;j<=i;++j)
           {
               scanf("%d",&a[i][j]);
           }
       }
       printf("%d\n",poj(1,1));
    return 0;
}

poj()

int poj(int x,int y)
{
    //现在是递归的使用
    //如果说到达最下面的那一行,直接输出
    if(x==n)
        return a[x][y];
    int num1=poj(x+1,y);//这个代表的是左边的数字
    int num2=poj(x+1,y+1);//这个代表的是右边的数字

    return max(num1,num2)+a[x][y];


}

用这种方法很容易得到了结果

但是

提交后是时间超时。

为什么超时?因为在计算的时候重复计算了!!!!时间复杂度是2的n次方,这是一个非常大的数,大到就算是宇宙毁灭也计算不出来结果。

如果说每次在计算的时候把这个值给保存下来,那么以后计算的时候可以直接使用,这个时候的时间复杂度为O(n*n);

下面是数字三角形的记忆递归型动规程序:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=105;//最大的数据
int n;
int a[maxn][maxn];
int maxsum[maxn][maxn];
int poj(int x,int y)
{
    if(maxsum[x][y]!=-1)
        return maxsum[x][y];
    //现在是递归的使用
    //如果说到达最下面的那一行,直接输出
    if(x==n)
        return maxsum[x][y]=a[x][y];
    int num1=poj(x+1,y);//这个代表的是左边的数字
    int num2=poj(x+1,y+1);//这个代表的是右边的数字
    return maxsum[x][y]=max(num1,num2)+a[x][y];
}
int main()
{
       scanf("%d",&n);
       for(int i=1;i<=n;++i)
       {
           for(int j=1;j<=i;++j)
           {
               scanf("%d",&a[i][j]);
               maxsum[i][j]=-1;
           }
       }
       printf("%d\n",poj(1,1));
    return 0;
}

不过,我们不用写递归程序,用循环递推也可以解决。

从最底层开始,一层层往上推

这个时候问题来了,每层在向上走的时候,下面的数字已经没有用了,那么我们就可以用以为数组来表示。

用一维数组记录每一行出现的数字的大小,那是不是也可以用数组a来表示呢?

答案是肯定的,从底层开始,一层层向上相加,最后就是答案。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=105;//最大的数据
int n,*maxsum;
int a[maxn][maxn];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=i;++j)
        scanf("%d",&a[i][j]);
    maxsum=a[n];
    for(int i=n-1;i>=1;--i)
        for(int j=1;j<=i;++j)
        maxsum[j]=max(maxsum[j],maxsum[j+1])+a[i][j];
    printf("%d\n",maxsum[1]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zbq_tt5/article/details/85331774