AtCoder Grand Contest 049 Increment Decrement

题意

对于长度为\(n\)的序列\(\{A_i\}\),可以进行两种操作:
(1):选择一个位置\(+1\)\(-1\),花费为\(1\)
(2):选择任意区间\(+1\)\(-1\),花费为\(C\)
一个序列的花费将其变为\(0\)的最小花费
给定\(K\),给定族\(\{B_i\}(i\in[1,n],|B_i|=K)\)
\(A_i\)可以使可重集合\(B_i\)中的任意元素,求\(\{A\}\)\(k^n\)种方案的最小花费之和
\(n,c,K\in [1,50],B_{i,j}\in[1,10^9]\)

如果看不懂下面怎么用维护分段函数的方法dp,可以先去做一下超级弱化版cf335F

做法

结论1:对于长度为\(n\)的序列\(\{a_i\}(a_i\ge 0)\)(假定边界\(a_0=a_{n+1}=0\)),如果每次只能选择任意区间(操作\(2\)),最小操作次数为\(\sum\limits_{i=1}^n max(0,a_i-a_{i-1}),\sum\limits_{i=0}^n \frac{|a_i-a_{i+1}|}{2}\)(两者没有直接关系)

proof
首先通过调整法,容易证明存在最优解每次操作都可以选择\(-1\)
(1)\(\sum\limits_{i=1}^n max(0,a_i-a_{i-1})\)
考虑归纳,操作完\(1\sim n-1\),末尾添加\(a_n\),增量显然为\(max(0,a_n-a_{n-1})\)
(2)\(\sum\limits_{i=0}^n \frac{|a_i-a_{i+1}|}{2}\)
\(b_i=|a_i-a_{i-1}|\)
每次操作将\(b_l,b_{r+1}\)\(1\)

对于此题,选择\(\sum\limits_{i=0}^n \frac{|a_i-a_{i+1}|}{2}\)更方便
由于操作有可交换性,我们先使用操作\(1\)将序列变成\(\{b_i\}\),然后操作\(1\)的次数显然等于\(\sum\limits_{i=1}^n |a_i-b_i|\)
那么总的花费为:\(C\cdot \sum\limits_{i=0}^n \frac{|b_i-b_{i+1}|}{2}+\sum\limits_{i=1}^n |a_i-b_i|\)

\(f_{i,j}\)\(b_i=j\)时前\(i\)个数的最小花费(为方便计算,避免分数的出现,将花费\(\times 2\)

\[f_{i,j}=\min\limits_{k} \{f_{i-1,k}+C\cdot |j-k|+2|a_i-j|\} \]

结论2\(f_{i}\)为凸函数,且为一次函数的分段函数

proof
忽略\(2|a_i-j|\),其显然不影响我们的结论
\(i=1\sim n\)施归纳
考虑\(f_{i-1}\)\(f_i\)的转移
对于\(f_{i-1}\)上某点\(j\)\((j,f_{i-1,j})\)),设其斜率为\(k\)
(1):\(|k|\le C\),则\(f_{i,j}\)必定由\(f_{i-1,j}\)转移过来
(2):\(k<-C\),则\(f_{i,j}\)\(f_{i-1,j'}\)转移(\(j'\)是离\(j\)最近的斜率\(\ge -C\)的位置)
(3):\(k>C\),则\(f_{i,j}\)\(f_{i-1,j'}\)转移(\(j'\)是离\(j\)最近的斜率\(\le C\)的位置)

现在我们已经大概知道了\(f\)的样子,考虑\(f_i\)\(f_{i-1}\)的函数间的联系(先不考虑\(2|a_i-j|\)
(1):对于\(|k|\le C\),其值不变
(2):对于\(k<-C\)的部分,其斜率变为\(-C\)
(3):对于\(k>C\)的部分,其斜率变为\(C\)
再考虑进\(2|a_i-j|\)
(4):\(a_i\)左边的部分,斜率\(-2\)\(a_i\)右边的部分,斜率\(+2\)

\(g_{i,j}=f_{i,j}-f_{i,j-1}(j>0)\)\(g_{i,0}=f_{i,0}\)
那么对于\(g_{i-1}\)\(g_i\)的转移
(1)对\(-C\)\(max\),对\(C\)\(min\)
(2)\([1,a_i]\)整体减\(2\)\((a_i,\infty)\)整体加\(2\)
对于\(g_{i,0}\)根据dp的定义,有:

\[g_{i,0}=g_{i-1,0}+2|a_i-0|+\min\limits_{k=1}^{\infty}\{\sum\limits_{j=1}^k g_{i-1,j}+kC\} \]

由于\(g_{i,j}(j>1)\)关于\(j\)单调不降,有

\[g_{i,0}=g_{i-1,0}+2|a_i-0|+\sum\limits_{j=1}^{\infty} min(0,g_{i-1,j}+C) \]

\(a_{n+1}=0\),答案即为\(g_{n+1,0}=\sum\limits_{i=0}^n (2a_i+\sum\limits_{j=1}^{\infty} min(0,g_{i,j}+C))\)

下面考虑计数
我们怎么统计\(k^n\)的答案呢?
观察1\(j\)的范围只会达到\(max\{a_i\}\)

观察2:若我们对\(\{a_i\}\)排序得到序列\(\{c_i\}\)\(\forall i,j\in[1,n],g_{j,v}(v\in(c_{i-1},c_{i}])\)均相同

proof
考虑归纳,根据\(g_{i-1}\)\(g_i\)的转移易证

观察3\(\forall i,g_i\in[-C-2,C+2]\)

proof
每次转移时会缩紧

我们将\(\{B_{i,j}\}\)排序,对\(j\in (l,r]\)\(g_{i,j}(i\in[1,n])\)统计
\(h_{i,k}\)为上述状态中\(g_{i,j}=k\)的方案数,具体转移可以看一下代码
时间复杂度\(O(n^2KC)\)

坑点:注意\(g_{0,j}\)的初始值为\(|j-0|C\)

code

code

posted @ 2020-11-21 16:49  Grice  阅读(139)  评论(0编辑  收藏  举报