这是一个好东西->作者主页
题目大意
给你一个 n ∗ m n*m n∗m的图,有一些柱子,你要操控小鸟飞过柱子的缝隙,点击屏幕可以让小鸟飞 x x x的高度,否则将会掉落 y y y的高度,求能否到达终点。如果能,输出 1 1 1和最少点击屏幕数;否则输出 0 0 0和最多飞过的柱子数量。
思路
第一眼看过去:
5 ≤ n ≤ 10000 5\leq n\leq 10000 5≤n≤10000
5 ≤ m ≤ 1000 5\leq m\leq 1000 5≤m≤1000
必定是动态规划(不然数据出这么大干啥)。
我们设
f
i
,
j
,
0
/
1
f_{i,j,0/1}
fi,j,0/1表示到了
i
i
i列
j
j
j行,刚才是飞上来还是掉下来,最少点击的屏幕数。
当发现第
i
i
i列的所有
f
i
,
j
,
0
/
1
f_{i,j,0/1}
fi,j,0/1都是无穷大时,输出所经过的管道数-1。
转移
- 从上一列飞上来: f i , j , 0 = m i n ( f i − 1 , j − x [ i − 1 ] , 0 , f i − 1 , j − x [ i − 1 ] , 1 ) + 1 f_{i,j,0}=min(f_{i-1,j-x[i-1],0},f_{i-1,j-x[i-1],1})+1 fi,j,0=min(fi−1,j−x[i−1],0,fi−1,j−x[i−1],1)+1
- 从这一列多点几次飞上来: f i , j , 0 = m i n ( f i , j , 0 , f i , j − x [ i − 1 ] + 1 ) f_{i,j,0}=min(f_{i,j,0},f_{i,j-x[i-1]}+1) fi,j,0=min(fi,j,0,fi,j−x[i−1]+1)
- 从上一列掉下来: f i , j , 1 = m i n ( f i − 1 , j + y [ i − 1 ] , 0 , f i − 1 , j + y [ i − 1 ] , 1 ) f_{i,j,1}=min(f_{i-1,j+y[i-1],0},f_{i-1,j+y[i-1],1}) fi,j,1=min(fi−1,j+y[i−1],0,fi−1,j+y[i−1],1)
细节
- 枚举范围: 1 ≤ i ≤ n 1\leq i\leq n 1≤i≤n, 1 ≤ j ≤ m + x [ i − 1 ] 1\leq j \leq m+x[i-1] 1≤j≤m+x[i−1]
- 管道没有说按顺序输入
- 当 j j j大于 m m m时, f i , j , 0 / 1 f_{i,j,0/1} fi,j,0/1要改成 f i , m i n ( m , j ) , 0 / 1 f_{i,min(m,j),0/1} fi,min(m,j),0/1
- 初始化:第 0 0 0列为 0 0 0,其他为 I N F INF INF
- 如果可以飞过,答案取值为 ( 1 ≤ j ≤ m ) (1\leq j\leq m) (1≤j≤m) m i n ( f n , j , 0 / 1 ) min(f_{n,j,0/1}) min(fn,j,0/1)
小提示:
- 文章某个地方有一个小链接
- 记得一键三连哦