简要题意
给定长度为 \(n\le2\times10^5\) 的序列 \(1\le A_i<10^9\) ,定义 \(f(x)\) 为 \(x\) 的数位和如 \(f(153)=9\) ,求 \(\min\limits_{x\ge 0}\sum\limits_{i=1}^nf(A_i+x)\) 。
题解
在英语课上手玩了一下这题,先不考虑 \(+x\) 先考虑 \(+1\) ,那么我们发现对于某个数 \(a\) , \(f(a+1)=f(a)+1-9\cdot\#进位\) 如 \(f(99+1)=f(99)+1-9*2=1\) 。
于是有一个自然想法把 \(f(A_i+x)\) 拆成 \(f(A_i)+x-9\cdot\#进位\) ,就是把 \(x\) 拆成 \(x\) 个 \(+1\) ,总过程中有几个进位,那么对于给定 \(x\) 答案就是 \(\sum f(A_i)+nx-9\sum\#进位_i\) 。
然后显然这个进位是具有周期的,例如连续 \(9\) 个 \(0\) 之类的,可以化为一个比较好的形式,考虑把进位拆开,就是 \(\#进位_i=\sum\limits_k\lfloor\dfrac{x-(10^k-A_i\%10^k)}{10^k}\rfloor\) ,然后显然 \(10^k-A_i\%10^k\) 这个东西是确定的,且能排出一个大小,当时想着就是依据大小来搞 \(dp\) 类似物,但是下课了,也就去恰饭了。
后来看了看题解感觉总的过程差不多,不过初始的考虑不太一样,题解就是按位确定 \(x\) ,考虑 \(F(Array)\) 表示对于给定 \(Array\) 的答案, \(F_r(Array)\) 表示最低位为 \(r\) 的时候的答案,如 \(F_1(\{123,45,678,90\})=20+F(\{12,4,67,9\})\) ,然后显然 \(F(Array)=\min\limits_rF_r(Array)\) 那么这样子就能把问题转化为一个子问题。
然后我们需要考虑进位问题,进位也是有规律的,根据 \(A_i\%10^k\) 的大小从大到小依次进位,不会出现小的进了大的没进这种情况,就可以设计 \(dp\) 状态 \(f_{k,n}\) 表示考虑 \(\{A_i/10^k\}\) 且有 \(n\) 位进位时的答案,那么终态就是 \(f_{0,0}\) ,初态为 \(f_{\infty,i}=i\) ,转移的时候存一下几个进位了就好,然后写得优雅一点就好了。 \(O(nk\log n)\) 。
Code
1 | const int N = 200100; |