Atcoder abc310
https://atcoder.jp/contests/abc310/tasks
Ex - Negative Cost
$h \in [1,10^{18}]$
p = 0
n个($[1,300]$) $c_i [-300,300]$,$d_i [1,10^9]$
每次可以 任选一个p(可重复选), 满足$p \ge c_i$, 然后 $p -= c_i$, $h -= d_i$
问最少多少次 让 $h \le 0$
3s
1024mb
我的思路
先预处理数据
sort pair{ci,di}
对于 $c_i \le c_j, d_i \ge d_j$, 舍去 {cj,dj}
因为首先单次ci代价越小,di越多越好
dp[i][t][p] =
前i个 操作t次, p的结束值 能消耗最大的h
dp[i][t+k][p-k*ci] = max dp[i-1][t][p]
显然空间都存不下
考虑预处理后的数据
排序后前部分的 -k*ci > 0
题解
$L=300$,是 |c|
的上界
也是 简化一下题意,就是选择的前缀 -C
的和 $\ge 0$
令 所有前缀和 $\le 2L$,的方案为 basic方案
性质1, 任何合法方案 可以转换称对应的basic方案
c: [...](>=L) >0, <0
, 则交换后两个,这样保证了 前缀和合法的情况下,拆成[.......<0]
一段basic和很多 >=0
的单个basic
性质2: basic方案 可以拆分成 多个 长度不大于2L
的
因为前缀和 <= 2L, 所以容斥原理存在两个前缀相同
[....][...=0][...]
, 把中间这段拆出来sort一下再拆分,两端直接拼接,可以无限递归下降直到长度<=2L
综上, 变成了任何方案 一定可以拆分成 多个 长度<=2L
, 且 前缀和保持 [0,2L]
的段的拼接
满足上述情况下
dp[i][j] =
长度i,和为j的最大 D的消耗
2L 2L
个状态,转移代价n倍
处理后 问题变为 2L个东西,第i个东西代价i,消耗Di,要让 代价和
尽量小,消耗和
>= h
令z={代价,消耗}
是上面2L东西中di/i
最大的,用它来拼h,可以完成,但不一定最优
而在最优的方案中,如果存在2L个不是z的
那么这2L的组合的 代价和 取mod z.代价
.再次抽屉原理 至少有两个前缀是mod z.代价
相同的,那它们之间的差是z.代价
的倍数, 替换成z
不会更差
所以 最优方案中, 最多有<2L
个不使用z
所以现在 如果不一定用z的消耗和为$h_0$,那么剩余用z,就是$\lceil \frac{h-h_0}{h}\cdot z_{代价}\rceil$的代价
dp2[i][j]
, 用前i个东西,代价和为j的最大消耗,注意到j的范围在 $(2L)^2$, O(1)转移代价
代码
https://atcoder.jp/contests/abc310/submissions/48959505
1 |
|
总结
Ex
这两个性质推断的方向,看得我一愣一愣的
后面两次的抽屉原理得到性质,也自己没有想到