Minimizing Maximizer(POJ No.1769)

Minimizing Maximizer(POJ No.1769)

Maximizer是一个接受 n n 个数作为输入,并输出它们的最大值的装置。这个装置由 m m 个叫做Sorter的装置依次连接而成。第 k k 个Sorter把第 k 1 k-1 个Sorter的输出作为输入,然后将第 s k s_k 到第 t k t_k 个值进行排序后,保持其余部分不变输出。Maximizer的输入就是第一个Sorter的输入,最后一个Sorter的输出就是Maximizer的输出。从组成Maximizer的Sorter中去掉几个之后,Maximizer有可能还可以正常工作。现在给定Sorter的序列,求其中的最短的一个子序列(可以不连续)使得Maximizer仍然可以正常工作。
2 n 50000 , 1 m 500000 , 1 s k < t k n (2\leq n \leq 50000,1 \leq m \leq 500000,1 \leq s_k < t_k \leq n)

输入

n = 40
m = 6

输出

4

题解

首先考虑一下在什么样的情况下可以正常工作。假设输入的第 i i 个数是应该输出的最大值。此时,在第一个满足 s k t k t k s_k \leq t_k \leq t_{k'} 的Sorter的输出中,这个值被移动到了第 t k t_k 个位置。

接下去,在第一个满足 s k t k t k s_{k'} \leq t_k \leq t_{k'} 的Sorter的输出中,这个值又被移动到第 t k t_{k'} 个。不断重复这样的操作,如果最后可以被移动到第 n n 个,那么就表示Maximizer可以正常工作。

在这里插入图片描述
因为只要对i=1的情况可以正常工作,那么对于任意的 i i 都可以正常工作。我们不妨假设输入的第一个数是应该输出的最大值

定义 d p [ i ] [ j ] dp[i][j] 表示到第 i i 个Sorter位置,最大值被移动到第 j j 个位置所需要的最短的子序列的长度( I N F INF 表示不存在这样的序列)

d p [ 0 ] [ 1 ] = 0 d p [ 0 ] [ j ] = I N F ( j > 1 ) d p [ i + 1 ] [ j ] { d p [ i ] [ j ] ( t j ) m i n ( d p [ i ] [ j ] , m i n { d p [ i ] [ j ] s i j t i } + 1 ) ( t i = j ) dp[0][1] = 0\\ dp[0][j]=INF(j>1)\\ dp[i+1][j] \begin{cases} dp[i][j](t \neq j)\\ min(dp[i][j], min\{dp[i][j']|s_i \leq j' \leq t_i\}+1)(t_i=j) \end{cases}

由于这个 D P DP 的复杂度是 O ( n m ) O(nm) 的,仍然无法在规定时间内求出答案。但是对于 t i j d p [ i + 1 ] [ j ] = d p [ i ] [ j ] t_i \neq j时有dp[i+1][j]=dp[i][j] 。如果我我们使用同一个数组不断对自己更新又会怎样呢?

定义 d p [ j ] dp[j] 表示最大值被移动到第 j j 个位置所需要的最短的子序列的长度( I N F INF 表示不存在这样的序列)

进行一下初始化: d p [ 1 ] = 0 , d p [ j ] = I N F ( j > 1 ) dp[1]=0,dp[j]=INF(j>1)
对于每个 i i ,这样更新:
d p [ t i ] = m i n ( d p [ t i ] , m i n { d p [ j ] s i j t i } + 1 ) dp[t_i]=min(dp[t_i],min\{dp[j']|s_i \leq j' \leq t_i\}+1)

这样,对于每一个 i i 都只需要更新一个值就可以了。但是可能会认为求解最小值时,最坏的情况下仍然要 O ( n ) O(n) 的时间,最后复杂度还是 O ( n m ) O(nm) 。不过,如果使用之前介绍的线段树来维护,就可以在 O ( m   l o g   n ) O(m\ log\ n) 的时间内求解了。

发布了163 篇原创文章 · 获赞 54 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_42856843/article/details/102385264
今日推荐