#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)
可以用滚动数组优化空间。

浙公网安备 33010602011771号