hihoCoder 1037 数字三角形

6 篇文章 0 订阅
6 篇文章 0 订阅
这篇博客介绍了hihoCoder上的第1037题——数字三角形,涉及动态规划的解题思路。博主分析了问题的无后效性和重复子问题,并给出了AC代码链接,旨在帮助读者理解如何计算小Ho在数字三角形迷宫中能获得的最多奖券数。
摘要由CSDN通过智能技术生成

数字三角形

问题描述

小Hi和小Ho在经历了螃蟹先生的任务之后被奖励了一次出国旅游的机会,于是他们来到了大洋彼岸的美国。美国人民的生活非常有意思,经常会有形形色色、奇奇怪怪的活动举办,这不,小Hi和小Ho刚刚下飞机,就赶上了当地的迷宫节活动。迷宫节里展览出来的迷宫都特别的有意思,但是小Ho却相中了一个其实并不怎么像迷宫的迷宫——因为这个迷宫的奖励非常丰富~

于是小Ho找到了小Hi,让小Hi帮助他获取尽可能多的奖品,小Hi把手一伸道:“迷宫的介绍拿来!”

小Ho选择的迷宫是一个被称为“数字三角形”的n(n不超过200)层迷宫,这个迷宫的第i层有i个房间,分别编号为1..i。除去最后一层的房间,每一个房间都会有一些通往下一层的房间的楼梯,用符号来表示的话,就是从第i层的编号为j的房间出发会有两条路,一条通向第i+1层的编号为j的房间,另一条会通向第i+1层的编号为j+1的房间,而最后一层的所有房间都只有一条离开迷宫的道路。这样的道路都是单向的,也就是说当沿着这些道路前往下一层的房间或者离开迷宫之后,小Ho没有办法再次回到这个房间。迷宫里同时只会有一个参与者,而在每个参与者进入这个迷宫的时候,每个房间里都会生成一定数量的奖券,这些奖券可以在通过迷宫之后兑换各种奖品。小Ho的起点在第1层的编号为1的房间,现在小Ho悄悄向其他参与者弄清楚了每个房间里的奖券数量,希望小Hi帮他计算出他最多能获得多少奖券。
输入
每个测试点(输入文件)有且仅有一组测试数据。

每组测试数据的第一行为一个正整数n,表示这个迷宫的层数。

接下来的n行描述这个迷宫中每个房间的奖券数,其中第i行的第j个数代表着迷宫第i层的编号为j的房间中的奖券数量。

测试数据保证,有100%的数据满足n不超过100

对于100%的数据,迷宫的层数n不超过100

对于100%的数据,每个房间中的奖券数不超过1000

对于50%的数据,迷宫的层数不超过15(小Ho表示2^15才3万多呢,也就是说……)

对于10%的数据,迷宫的层数不超过1(小Hi很好奇你的边界情况处理的如何?~)

对于10%的数据,迷宫的构造满足:对于90%以上的结点,左边道路通向的房间中的奖券数比右边道路通向的房间中的奖券数要多。

对于10%的数据,迷宫的构造满足:对于90%以上的结点,左边道路通向的房间中的奖券数比右边道路通向的房间中的奖券数要少。

输出
对于每组测试数据,输出一个整数Ans,表示小Ho可以获得的最多奖券数。

样例输入
5
2
6 4
1 2 8
4 0 9 6
6 5 5 3 6
样例输出
28

问题分析

典型的动态规划题,该问题存在两个特征,无后效性和重复子问题
无后效性:无论我是通过怎么样的方式到达第i层第j个房间的,我之前做出的选择不会对我之后的选择做出限制与优待。所谓的限制与优待指的是不会有走法的次数限制
重复子问题:<3,2>这个房间会被<2,1>和<2,2>计算两次,这就是重复子问题。

综合两个子问题,我们用best(i,j)表示到达

AC代码

import java.util.Scanner;

/**
 * Created by Jason on 2016/4/13.
 */
public class Main {

    public static int getMaxValue(int[][] values,int size) {
        int maxValue = 0;
        int[][] best = new int[size][size];
        best[0][0] = values[0][0];
        for (int i=1;i<size;i++) {
            for (int j=0;j<=i;j++) {
                if (j==0) {
                    best[i][j] = best[i-1][j] + values[i][j];
                } else if (j==i) {
                    best[i][j] = best[i-1][j-1] + values[i][j];
                } else {
                    best[i][j] = Math.max(best[i-1][j-1],best[i-1][j]) + values[i][j];
                }
            }
        }
        for (int i=0;i<size;i++) {
            if (best[size-1][i]>maxValue) {
                maxValue = best[size-1][i];
            }
        }
        return maxValue;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int size = scanner.nextInt();
        int[][] matrix = new int[size][size];
        for (int i=0;i<size;i++) {
            for (int j=0;j<=i;j++) {
                matrix[i][j] = scanner.nextInt();
            }
        }
        System.out.println(getMaxValue(matrix,size));
    }

}

代码链接:
https://github.com/lincolnmi/hihoCoder/blob/master/src/Hi_1037/DigitalTriangle.java

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值