把船一直载满 $3$ 个人是不劣的,多的空位我们用船夫补就好。故枚举所有可能的情况:
- 一个船夫一直运输,把船上的两名游客送到对应目的地
- 一个船夫一直运输,把船上的一名游客送到对应目的地,然后把一个船夫送到某个岛上
- 一个船夫一直运输,然后把两个船夫送到某个岛上
- 三名游客自己运输,然后在某个岛上接上船夫,让这个船夫把船运回 $A$
然后允许船夫在 $B,C$ 岛不回来,因为真实情况下,如果有船夫在外面,我们在运他的时候干脆就不把他放下去就好了。
因为船夫具体在哪个岛不重要,我们只要知道「有几个船夫在 $B,C$ 岛上即可」,所以我们利用延迟贡献的思想,就是每次把船夫运出去时,不思考它运到哪里了,要用的时候再确定。
因为贡献计算只考虑 $t_i$ 最大的那个人,我们将 $i$ 个人按照 $t_i$ 从大到小排序,这么做有个好处,当我们要为这个人付费时,直接付费即可,后面的一些人就可以免费乘船。
意思是说,比如「一个船夫一直运输,把船上的两名游客送到对应目的地」这种情况,如果有一个 $t_i$ 较大的人坐船到 $B$ 岛,那么就可以免费带一个 $t_i$ 较小的人到 $B$ 岛。因为 $t_i$ 从大到小排序,较小的那个人就不会产生贡献。
利用这种思想去设计 dp:$F[i][x][y][z]$ 表示按 $t_i$ 从大到小排序的前 $i$ 个人已经计算过了贡献,有 $x$ 个可以免费去 $B$ 的机会和 $y$ 个免费去 $C$ 的机会,同时 $B,C$ 岛还剩下 $z$ 个船夫的最小花费时间。注意 $z$ 可以为负数,表示提前预支船夫。
接下来假设当前人去的是 $C$,去 $B$ 是类似的。转移如下:
- 送三个船夫出去(3 类船),$F[i-1][x][y][z+2]\gets F[i-1][x][y][z]+3$
- 载着一个游客,两个船夫出去一圈,放下一个船夫(2 类船),$F[i][x][y][z+1]\gets F[i-1][x][y][z]+2w_i+1$
- 自己开新的船,带一个船夫和一个到 $C$ 的人(1 类船),$F[i][x][y+1][z]\gets F[i-1][x][y][z]+2w_i+1$
- 有一个到 $B$ 的空位,支付改成 $C$ 的价格,$F[i][x-1][y][z]\gets F[i-1][x][y][z]+w_i-1$
- 有一个到 $B$ 的空位,支付改成 $C$ 的价格的情况,也有可能是三个人一起出发去 $B$,这种情况下如果把一个去 $B$ 的空位改成去 $C$ 的空位,也可以把最后剩下的那个到 $B$ 的空位免费改成到 $C$ 的空位,$F[i][x-2][y+1][z]\gets F[i-1][x][y][z]+w_i-1$。当然这种情况也会把单独开了两只送 $B$ 的船混淆,但是分析之后发现产生混淆的情况一定不优,所以不会算错
- 有一个到 $C$ 的空位,免费使用了,$F[i][x][y-1][z]\gets F[i-1][x][y][z]$
- 三个游客一起出发,最后带回一个船夫,$F[i][x][y+2][z-1]\gets F[i-1][x][y][z]+2w_i+1$
此时复杂度非常大,不过我们发现,$x,y\le 2$。因为如果 $x\ge 3$,例如 $x=3$,一种情况是送了三只 1 类船到 $B$,那么贡献至少为 $3w_i+6$。而此时我们不如先送三个船夫出去(3 类船),然后再送两轮 4 类船,贡献是 $3+2w_i+4=2w_i+7$,前者一定不优于后者。其他情况也是类似分析即可。
而 $z\in[-1,2]$(实际上是 $[-1,1]$,但我懒得分析了),下界证明,最多只会预支 $1$ 个船夫,因为如果预支 $2$ 个船夫,不如直接先送三个船夫出去从而满足条件,这样花费会更少。借此也可以证明最多只会多两个船夫(更严格地证明可以证出只会多一个船夫)。
所以复杂度正确。
提交记录(其中注释请辩证性看待,不一定保证正确)