做题笔记 #6

终于可以自己用交换的方式推贪心式子了!后面的 dp 还挺套路的。

[P2577 ZJOI2004] 午餐 - 洛谷

两个打饭窗口

给出 n 个人的打饭时间 a 、吃饭时间 b ,这 n 个人分成两队排队,求最后一个人吃完的最快时间。

解法

这种题一看就知道要贪心。但目前还不知道要怎么贪。可能是交换证明。

有两个相邻的人 \((a_1,b_1), (a_2,b_2)\) 显然交换这两个人不会影响前面或后面的其他人。

1 号在前面的贡献 :\(\max a_1+b_1,a_1+a_2+b_2\).

2 号在前面的贡献 :\(\max a_2+b_2,a_2+a_1+b_1\).

要求两式的 min。小推一下。使用拆 max 的套路

  1. \(a_2+b_2 > a_2+a_1+b_1, b_2>a_1+b_1\),发现第一个 max 可以丢掉,因为后面的一定比前面的大(\(a_1+b_1 < a_1+a_2+b_2\))。又因为 \(a_2+b_2<a_1+a_2+b_2\),所以二式更优。
  2. \(a_2+b_2 < a_2+a_1+b_1\),法案先还是不能做,但发现 \(a_2+a_1+b_1 > a_1+b_1\),所以发现这本质上只是后一项在比大小。所以当 \(b1>b2\) 时,一式更优,\(b1<b2\) 时,二式更优。
  3. 然后发现情况一是:$ b_2>a_1+b_1$ 时,二式更优。相当于是“ \(b1<b2\) 时,二式更优“ 的强化,或者说充分条件,所以只需要比较 b 的大小就行了。

所以按照 b 升序就是最优的。

肯定是按 b 排序后,一个一个地把数加到队列里,然后考虑加到那个队列更优。

考虑 dp,猜一下可能有什么信息有用:队1排队时间,队1最大吃饭时间,队2排队时间,队2最大吃饭时间。再加上枚举现在是那个人的话就是 \(O(n (n^2)^3)\)。首先发现这是可行性背包,可以把某一维变成 dp 值,还发现我们一点都不关心是那一队吃的最慢,只要知道时间就行了,这是因为新加入一个数产生的贡献与之前谁吃得满无关。所以设 \(dp_{i,t_1,t_2}\) 表示第 i 个人,队1排队时间,队2排队时间的最小总时间。然后又发现,如果枚举了 i 和 t1,就可以把 t2 直接算出来。转移方程的话随便写:

\[dp_{i,t1} = \min(\max({dp_{i-1,t1-a_i},t_1+b_i}),\max(dp_{i-1,t1},sa_i-t_1+b_i)) \]

好像有一个叫刷表法的神秘玩意,有时间学一下。

posted @ 2025-03-26 09:06  花子の水晶植轮daisuki  阅读(32)  评论(0)    收藏  举报
https://blog-static.cnblogs.com/files/zouwangblog/mouse-click.js