以此题为例跳楼机,将题目转化为数学表达式即为求存在多少个 d d d 满足 d ∈ [ 1 , h ] d\in[1,h] d∈[1,h] 且 a x + b y + c z = d ax+by+cz=d ax+by+cz=d。为了方便起见我们将 d d d 的范围设为 [ 0 , h − 1 ] [0,h-1] [0,h−1]。
首先我们需要知道如果存在一个数字 d 1 d_1 d1 他满足我们题目的要求,那么 d 1 + x d_1+x d1+x 一定也满足我们的要求(假设 d 1 + x d_1+x d1+x 不会越界),那么如果此时我们知道了 b y + c z by+cz by+cz 的所有满足条件的数集 A A A ,轻易可知最终 d d d 的个数一定等于 A i + a x ∈ [ 0 , h − 1 ] A_i+ax∈[0,h-1] Ai+ax∈[0,h−1] 的 A i + a x A_i+ax Ai+ax 的个数,其中 a a a 满足 A i + a x < h A_i+ax<h Ai+ax<h。
此时你会发现 A A A 的元素太多了!而且 A i + a x A_i+ax Ai+ax 是会重复计算的,那怎么办呢?此时我们现思考一个问题,若取集合 A A A 中 A i , A j A_i,A_j Ai,Aj 满足 A i < A j A_i<A_j Ai<Aj 且 A i ≡ A j ( m o d x ) A_i\equiv A_j \pmod x Ai≡Aj(modx) ( x x x 为题目中的 x x x)那么 A j + a x A_j+ax Aj+ax 能得到的数字 A i + a x A_i+ax Ai+ax 同样也可以得到,那我们为什么要留下 A j A_j Aj 呢?所以我们 A A A 中第 i i i 个元素应该为:最小的 b x + c z bx+cz bx+cz 满足 b x + c z ≡ i ( m o d x ) bx+cz\equiv i\pmod x bx+cz≡i(modx) 。
那我们怎么求出最小的 A i A_i Ai 呢,这里有一个非常女少白勺做法,我们对于 i ∈ [ 0 , x ) i\in[0,x) i∈[0,x) 连边。
i → ( ( i + y ) m o d x ) i \rightarrow ((i+y)\mod x) i→((i+y)modx) 边权为 y y y, i → ( ( i + z ) m o d x ) i \rightarrow ((i+z)\mod x) i→((i+z)modx) 边权为 z z z,当我们想求 A i A_i Ai 时就可以直接求 0 0 0 到 i i i 的最短路径了。
代码和细节不多赘述。