POJ 1163 The Triangle【DP】递归和递推

本文介绍了一个经典的动态规划问题——寻找三角形路径中的最大和。通过递归与递推两种方法对比,展示了如何优化算法减少不必要的计算,实现高效的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

大体思路:

    这大概是最简单的DP题了把,其实直接用递归暴力解也能算出答案,但多出了太多没有必要的重复计算。所以需要DP来简化操作
    而简化操作则分为两个方法,分别对应递归和递推

递归代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int a[100][100];
int maxsum[100][100];//简化计算部分,将计算过的每次结果进行记录,从而减少计算量
int Dp(int i,int j,int n)
{
    if(i==n-1)
        return a[i][j];
    if(maxsum[i][j]==-1)
        maxsum[i][j]=a[i][j]+max(Dp(i+1,j,n),Dp(i+1,j+1,n));
    return maxsum[i][j];
}

int main()
{
    //freopen("in.txt","r",stdin);
    int n;
    while(cin>>n)
    {
        memset(maxsum,-1,sizeof(maxsum));
        for(int i=0;i<n;++i)
            for(int j=0;j<=i;++j)
                cin>>a[i][j];
        cout<<Dp(0,0,n)<<endl;
    }
    return 0;
}

递推代码:

与递归不同,递归的想法是从最底层进行计算,每层的最优结果放在一个一维数组里。得出最后的结果。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
int main()
{
    int n,a[100][100];
    while(cin>>n)
    {
        for(int i=0;i<n;++i)
            for(int j=0;j<=i;++j)
                cin>>a[i][j];
        int maxsum[100];//滚动数组,记录最有结果,
        for(int i=n-1;i>=0;--i){
            for(int j=0;j<=i;++j){
                if(i==n-1)
                    maxsum[j]=a[i][j];
                else
                    maxsum[j]=a[i][j]+max(maxsum[j],maxsum[j+1]);
            }//覆盖掉上一次的计算结果,因为没有用了。
        }
        cout<<maxsum[0]<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值