动态规划题目--数塔(HDU)

本文通过解决数塔问题介绍了动态规划的基本思想。通过对比贪心算法,展示递归及递推方法找到从数塔顶部到底部路径的最大和。提供了一个Java实现的例子。

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

因为之前没有怎么接触过算法,在赛码网上刷题,碰上了动态规划类的题目。正好借此机会系统的学习一下。

在哔哩哔哩上看算法视频,里面讲解了一道HDU上的题目,下面贴下题目描述:

ime Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 36261    Accepted Submission(s): 21659


 

Problem Description

在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的:

有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?

已经告诉你了,这是个DP的题目,你能AC吗?

 

Input

输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。

 

 

Output

对于每个测试实例,输出可能得到的最大和,每个实例的输出占一行。

 

 

Sample Input

1

5

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

 

 

Sample Output

30

解题思路:在不了解动态规划题目之前,应该首先想到的就是贪心吧,从顶想下,每次找最大的。经过测试,得到的结果为26。不如给出的样例结果大,贪心算法宣告失败。

递归的思路比较好想:顺着题目,我们从上往下看。第一层的节点没有什么好说的,他只有一个,但是到了第二层,节点就变成了两个。这就遇到了一个“选还是不选“的问题。假如我们选了第一个节点,而不选第二个节点。问一下自己,为什么不选第二个节点?当然是第一个节点的值大呗(注意了,上一段中我们已经说了,贪心的方法行不通,所以这里的”值大“代表经过处理后的值,怎么处理。。。下面讲)。同样的方法,继续进行第3,4,···n-1层的选择处理,到了第n层(递归的出口),选出较大的节点值,然后在进行回溯,就解决了。

经过递归思路的分析,注意到第n-1层依赖于第n层。所以我们只需将第n-1层各节点中子节点的最大值加上他们本身即可。如此向上处理。第一层的那个节点的值就是我们求的最大值。这里用的是递推的思想:从底向下分析。

代码:

import java.util.*;

public class Main {
    public static int dp_numberta(int[][] arr,int n){

        for(int i=n-2;i>=0;i--){
            for(int j=0;j<=i;j++){
                arr[i][j] = Math.max(arr[i+1][j],arr[i+1][j+1])+arr[i][j];
            }
        }
        return arr[0][0];
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        for(int k = 0;k<n;k++){
            int N = sc.nextInt();
            int[][] arr = new int[N][N];
            for(int i=0;i<N;i++){
                for (int j=0;j<=i;j++){
                    arr[i][j] = sc.nextInt();
                }
            }
            System.out.println(dp_numberta(arr,N));
        }

    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值