zoukankan      html  css  js  c++  java
  • 洛谷P3403 跳楼机(最短路)

    题目背景

    DJL为了避免成为一只咸鱼,来找srwudi学习压代码的技巧。

    题目描述

    Srwudi的家是一幢h层的摩天大楼。由于前来学习的蒟蒻越来越多,srwudi改造了一个跳楼机,使得访客可以更方便的上楼。
    经过改造,srwudi的跳楼机可以采用以下四种方式移动:
    向上移动x层;
    向上移动y层;
    向上移动z层;
    回到第一层。
    一个月黑风高的大中午,DJL来到了srwudi的家,现在他在srwudi家的第一层,碰巧跳楼机也在第一层。DJL想知道,他可以乘坐跳楼机前往的楼层数。

    输入格式

    第一行一个整数h,表示摩天大楼的层数。
    第二行三个正整数,分别表示题目中的x, y, z。

    输出格式

    一行一个整数,表示DJL可以到达的楼层数。

    输入

    15
    4 7 9

    输出

    9

    输入

    33333333333
    99005 99002 100000

    输出

    33302114671

    提示

    可以到达的楼层有:1,5,8,9,10,12,13,14,15
    想不出来不要死磕这一题,先看看第三题。。。。
    1<=h<=(2^{63})-1
    1<=x, y, z<=100000


    假设可以到达的楼层为t
    我们可以得到一个方程:t=ax+by+cz
    如果设t'=by+cz,原方程就变成了t=a'x+t'

    f[i]表示表示仅通过操作2和操作3能到达的mod x == i的最小楼层t'
    (这里为什么要是最小楼层呢,举个栗子:x == 5时,7和12都满足mod x == 2.而12 = 7 +5,表示12层可以被后面讨论操作一的时候枚举到)
    注意:一定要把f[i]的i与f[i]的含义分开,i是f[i] mod x的结果,即i == f[i]%x

    状态转移方程:

    f[i+y] = f[i]+y;
    f[i+z] = f[i]+z;

    最短路方程:

    dis[b]=dis[a]+Len[a][b];

    我们把f[i+z]看做dis[b],把f[i]看做dis[a],将z看做b[(i+z)%x]点和a[i]点之间的边权(y同理)
    在这里,(i+y)%x的是防止i+y超过x

    建图过程:

    void add(int x,y,a){
        End[++tot]=y;
        Len[tot]=a;
        Next[tot]=Last[x];
        Last[x]=tot;
    }
    ……
    for(int i=0;i<x;i++){//i从0到x-1
        add(i,(i+y)%x,y);
        add(i,(i+z)%x,z);
    }
    

    因为是求最小楼层t',所以用SPFA/Dijkstra解决

    通过SPFA/Dijkstra,我们已经求出了仅通过操作2和操作3能到达的mod x == i的最小楼层t'

    那么就可以很快的求出还剩几层楼可以跳:(h - f[i]),从而推出剩下仅通过操作一可以跳的楼层个数:(h - f[i])/x(向下取整,因为不能跳超过h层)
    再通过ans与它之间的联系算出答案:ans += (h - f[i])/x + 1(剩下可以跳的楼层个数+f[i]本身这一层楼)

    一个问题:如果到达f[i]之前有经过其他点,那么从ans += (h - f[i])/x + 1来看,并没有将到达f[i]之前经过的点的个数计入答案,是否存在漏算?
    举个栗子来解释:

    x=8,y=3,z=5,h=100
    f[7]=1+3+3=7
    

    i == 7
    ans = ans + (h-f[7])/x+1 == ans + (100-7)/7 +1 == ans + 14
    作为“中转站”:第4楼能够达到,却并没有被算在ans里
    回过头去看i == 4
    ans = ans + (h-f[4])/x+1 == ans + (100 - 4)/7+1 == ans + 9
    也就是说,第4楼在算第7楼之前就已经算过了,再次计入ans只会使答案出现重复

    最后吐槽一下,这是一道省选难度的Noip模拟题
    【因为蹲在墙角所以有回声的小声bbbbbbbbbbbbbbb...】

  • 相关阅读:
    053532
    053531
    053530
    053529
    053528
    RTSP和RTMP的区别是什么?
    RTSP、RTMP和HTTP协议的区别
    在C#中实现视频播放器
    wpf下基于opencv实现视频播放器
    C#实现视频播放器(Vlc.DotNet)
  • 原文地址:https://www.cnblogs.com/qwqq/p/11251055.html
Copyright © 2011-2022 走看看