洛谷P1107 [BJWC2008]雷涛的小猫 \color{green}{\text{洛谷P1107\ \ \ \ \ [BJWC2008]雷涛的小猫}} 洛谷P1107 [BJWC2008]雷涛的小猫
【
题
意
】
:
\color{blue}{【题意】:}
【题意】: 雷涛同学
非常的有爱心,在他的宿舍里,养着一只因为受伤被救助的小猫(当然,这样的行为是违反学生宿舍管理条例的)。在他的照顾下,小猫很快恢复了健康,并且愈发的活泼可爱了。
可是有一天,雷涛
下课回到寝室,却发现小猫不见了!经过一番寻找,才发现她正趴在阳台上对窗外的柿子树发呆……
在北京大学
的校园里,有许多柿子树,在雷涛
所在的宿舍楼前,就有
N
N
N 棵。并且这
N
N
N 棵柿子树每棵的高度都是
H
H
H。冬天的寒冷渐渐笼罩了大地,树上的叶子渐渐掉光了,只剩下一个个黄澄澄的柿子,看着非常喜人。而雷涛
的小猫恰好非常的爱吃柿子,看着窗外树上的柿子,她十分眼馋,于是决定利用自己敏捷的跳跃能力跳到树上去吃柿子。
小猫可以从宿舍的阳台上跳到窗外任意一棵柿子树的树顶。之后,她每次都可以在当前位置沿着当前所在的柿子树向下跳
1
1
1 单位距离。当然,小猫的能力远不止如此,她还可以在树之间跳跃。每次她都可以从当前这棵树跳到另外的任意一棵,在这个过程中,她的高度会下降
D
e
l
t
a
Delta
Delta 单位距离。每个时刻,只要她所在的位置有柿子,她就可以吃掉。整个吃柿子行动
一直到小猫落到地面上为止。
雷涛
调查了所有柿子树上柿子的生长情况。他很想知道,小猫从阳台出发,最多能吃到多少柿子?他知道写一个程序可以很容易的解决这个问题,但是他现在懒于写任何代码。于是,现在你的任务就是帮助雷涛
写一个这样的程序。
图为
N
=
3
,
H
=
10
,
D
e
l
t
a
=
2
N=3,H=10,Delta=2
N=3,H=10,Delta=2 的一个例子。小猫按照图示路线进行跳跃,可以吃到最多的
8
8
8 个柿子。
【
思
路
】
:
\color{blue}{【思路】:}
【思路】: 首先看一个
O
(
n
2
×
h
)
O(n^2 \times h)
O(n2×h) 的算法,即记
f
i
,
j
f_{i,j}
fi,j 表示当前在第
i
i
i 棵树,
j
j
j 的高度时的答案。我们有转移方程:
f i , j = max { f i , j + 1 f k , j + D e l t a ( 1 ≤ k ≤ n , k ≠ i ) f_{i,j}=\max \left \{ \begin{matrix} &f_{i,j+1}\\ &f_{k,j+Delta}(1 \leq k \leq n, k\neq i) \end{matrix} \right. fi,j=max{fi,j+1fk,j+Delta(1≤k≤n,k=i)
当然,这是不能过这道题的,需要优化。我们发现性能瓶颈都在 k k k 的枚举上,如果我们能把它省略掉,那就可以 O ( n × h ) O(n \times h) O(n×h) 完成此题。
我们发现对相同的 j j j,因为我们的猫可以随意从一棵树跳到另一棵树,所以我们需要的 i i i 是一定的,即我们可以记 d j = max { f i , j } ( 1 ≤ i ≤ n ) d_j=\max \{f_{i,j} \}(1 \leq i \leq n) dj=max{fi,j}(1≤i≤n),转移的第 2 2 2 条就可以写成:
f i , j = d j + D e l t a f_{i,j}=d_{j+Delta} fi,j=dj+Delta
有个问题,那不会出现调用 f i , j = f i , j + D e l t a f_{i,j}=f_{i,j+Delta} fi,j=fi,j+Delta 吗,不会,因为对于相同的 i i i,越小的 j j j 肯定 f i , j f_{i,j} fi,j 越大(至少不会更少),所以 f i , j + D e l t a f_{i,j+Delta} fi,j+Delta 没有 f i , j + 1 f_{i,j+1} fi,j+1 优。
【
代
码
】
:
\color{blue}{【代码】:}
【代码】: