#0008. 牛排

题目大意:

  正反两面牛排需要各煎恰好n秒。给定m个没有重叠的时间区间[L,R]且只能在这几个区间内翻面。问是否能煎数,若是求最少翻面次数。

  //这里的翻面是在每个时间点的末尾发生的。也就是说如果在第k秒从A面翻到B面,第k秒煎的还是A面

  n<=1e5, m<=100 Rmax<=2n

题目解法:

  最朴素的状态是f(i,j,k)表示考虑前i秒正反面分别被煎了j和k秒的最少翻面次数。观察到j+k=i,因此直接删掉一维。在观察到m很小且所有不能翻面都煎的是同一面我们把i那个维度的意义修改成考虑前i个区间。因此f(i,j)表示考虑前i个区间最后煎的那面煎了j秒的最少翻面次数。答案显然就是f(m,Rmax-n)(因为后面的2n-Rmax秒都是用来煎最后这个面的)。

  然后我们观察到对于每个区间只有三种操作:不翻面、翻1次面和翻2次面。因为显然所有翻偶数次面都可以转化为翻2次面,所有翻奇数次面都可以转化为翻1次面。这样我们就有了三种转移。

  不翻面:f[i][j]=f[i-1][j-(r[i]-r[i-1])]

  翻一次面:f[i][j]=f[i-1][k]+1, 其中r[i]-j-(r[i]-r[i-1])<=k<=r[i]-j-(l[i]-r[i-1])

  翻两次面:f[i][j]=f[i-1][k]+2, 其中j-(r[i]-r[i-1]-1)<=k<=j-(r[i]-r[i-1]-(r[i]-l[i]))

  显然从一段的最值转移可以用单调队列优化(或者st表线段树之类的会多一个log的东西)。写的时候要特别注意数组越界问题。k经常啥都取不到(因为还要满足0<=k<=n)

  可以用滚动数组优化空间。

posted @ 2020-05-16 23:13  Myrcella  阅读(97)  评论(0)    收藏  举报