Skip to content

Latest commit

 

History

History
 
 

LCP43.十字路口的交通

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

LCP43.十字路口的交通

令dp[i][j][k][t]表示当前时刻,东南西北各个路口待发车的编号分别是第i辆(也就是说已经开走了i辆车)、第j辆、第k辆、第t辆的时候,已经花费的最小时间。此时我们考虑在此形势下可以有几种合法的发车方案,计算在plans里面。其中的每个plan是一个4 bit的二进制数,表示对应的路口是否可以发车。比如0110,表示南路口和西路口可以同时发车且不会冲突,这样的话就可以更新未来的状态:dp[i][j+1][k+1][t] = min(dp[i][j+1][k+1][t], dp[i][j][k][t]+1

那么如何求这些plans呢?我们可以穷举所有的plan(总共2^4种可能),然后检查每个plan是否可行。怎么检查某个plan是否可行呢?我们先做这样的标记,将每个车道进行编号:

        6 7  
        | ^
        * |        
5 <--        <-- 0
6 -->        --> 1
        | ^
        * |
        3 2

这样的话,每一个路口的每一种行车路线都对应着一对车道的编号。比如说Map[0]['W'] = {0,5}表示东路口往西走的车辆,将会从0号车道变更到5号车道。Map[1]['E'] = {2,1}表示南路口往东走的车辆,将会从2号车道变更到1号车道。以此类推。于是我们有非常好的性质:我们将行车路线对应的一对车道编号想象成一个区间,那么任意不相互切割的区间(即要么完全分离、要么完全包含),一定对应着不冲突的行车路线。比如说Map[0]['N']={0,7}, Map[2]['W']={2,5}, Map[3]['S']={6,3},这三个路口的三辆车的行车路线是不冲突的,因为{0,7},{2,5},{3,6}这几个区间不互相切割。

由此我们可以对任何一个并行发车的plan做出判断是否合法,仅将合法的plan可以被dp[i][j][k][t]用来更新后续状态。最终的答案是输出dp[n0][n1][n2][n3],其中ni表示第i个路口的原始车辆数目。

此题还需要记忆化。对于dp[i][j][k][y]所对应的交通形势(比如说是“NWES”),存储下相应的plans。这样以后如果遇到相同的交通形势,直接调用对应的合法plans。