zoukankan      html  css  js  c++  java
  • 【HIHOCODER 1037】 数字三角形

    链接

    问题描述

    小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

    题解

    官方好像提供了两种思路

    1. ((i,j,k))代表从原点到第i层第j个得到奖券总数为k的状态。如果搜到一个新状态,且k<已得到的((i,j,k))那么直接抛弃,反之把这个新的状态替代掉之前得到的状态,这样,保证每个房间入队一次,时间为(O(n^2))
    2. (dp[i][j])代表从原点到((i,j))的最大获益,转移方程为$$dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+a[i][j]$$

    参考代码

    import java.io.*;
    import java.util.*;
    
    public class Main {
    	static final int N=(int)105;
    	static int dp[][]=new int[N][N],
    		a[][]=new int[N][N];
    	public static void main(String[] args){
    		Scanner sc=new Scanner(new InputStreamReader(System.in));
    		int n=sc.nextInt();
    		for(int i=1;i<=n;i++) {
    			for(int j=1;j<=i;j++) {
    				a[i][j]=sc.nextInt();
    			}
    		}
    		for(int i=0;i<=n;i++) {
    			for(int j=0;j<=n;j++) dp[i][j]=0;
    		}
    		dp[1][1]=a[1][1];
    		for(int i=2;i<=n;i++) {
    			for(int j=1;j<=i;j++) {
    				dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-1])+a[i][j];
    			}
    		}
    		int ans=0;
    		for(int i=1;i<=n;i++) ans=Math.max(ans, dp[n][i]);
    		System.out.println(ans);
    		sc.close();
    	}
    }
    
  • 相关阅读:
    PyQt5对话框
    PyQt5基础控件
    PyQt5主界面
    PyQt5入门
    ioctl太多虚拟内存不够用
    code principles
    Error: watch ENOSPC
    intelJ
    cas
    C的函数指针的作用,以及其赋值是弱类型的
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/7229028.html
Copyright © 2011-2022 走看看