NamomoCamp2020-div2-day1-dp 部分题解
New Year and Original Order (Good Bye 2017 G)
数位dp
用$f[d][i]$表示数字$d$在第$i$位上出现的次数,假设我们已知所有$f[d][i]$,则有
可惜的是$f[d][i]$未知,直接求$f[d][i]$也很难求
考虑下性质:所有数字升序排序
,转化一下求$f[d][i]$的思路,用$g[d][i]$表示$\ge d$的数字出现$\ge i$次的次数,那么有$f[d][i]=g[d][i]-g[d+1][i]$
$g[d][i]$依旧不好直接求,但可以先求$h[d][i]$:$\ge d$的数字出现恰好$i$次的次数,$g[d][i]=\sum_{j=i}^{n}h[d][j]$
$h$就可以直接求了,数位dp一下即可,状态$h[pos][d][i][limit]$,状态数$O(10N^2)$
$k$表示当前位枚举的数字,转移式
1 |
|
Financiers Game (CF 729 F)
dp,状态优化,记忆化搜索
先来想一个暴力的状态,$f[i][j][k][m]$表示左边取$i$个,右边取$j$个,上一步取了$k$,$m=0/1$表示轮到左/右边取,$f[i][j][k][m]$则表示该状态下的答案
转移显然,状态也记全了,但是这个空间是$N^3$的,开不下。
这题的要点在于注意到$k$的优化,来考虑一下能最大化$k$的情况,肯定是从$2$开始,每次都取$k+1$,即取${2,3,4,..,k}$,此时有$\sum_{i=2}^{k}{i}=\frac{(k+2)\times(k-1)}{2} \leq N$,化简一下,可以得到一个大约的范围$k\leq \sqrt{2N} $
然后再以类似的想法来考虑$j$的优化,首先把$j$从右边取j个
变成左右已取的个数之差
,考虑最大化$j$,则应该是左边每次取$k+1$,而右边每次取$k$,那么某一时刻,可以表示为 左边取 ${1,2,3,…,k-1,k} $,右边取 ${1,2,3,…,k-1} $,类似上面算一下,可得 $k\leq \sqrt{N} $,因此 $-\sqrt{N}\leq j\leq \sqrt{N} $
优化$j$和$k$后空间其实已经够了,本题内存限制$512MB$,这样大概是$300MB$
但其实$i$也可以优化,最大化$i$的情况与最大化$j$的情况类似,结果大约是$i\leq \frac{N+\sqrt{N}}{2} $,这样就可以跑过$256MB$限制的情况了,过程自己算吧
1 |
|
[ZJOI2012]波浪
咕
Game on Chessboard (CCPC 2019 秦皇岛 G)
咕
Fountains (ICPC 2020 上海 F)
咕
Sum (VK Cup 2019 Final D)
背包,分治
首先来看题目给出的特殊性质,每个数组单独来讲都是非递减的。
因此有一个结论,在最优方案中,不存在两个数组同时未取完的情况。使用反证法,如果存在两个数组同时未取完,这两个数组最后取的数分别为$x$和$y$,则若$x>y$,可以把$y$换成$x$右边的数,$x<y$则可以把$x$换成$y$右边的数。
换句话说,最优方案可以视作取完若干个数组,再外加一个取到一半的数组。
那么就诞生了一个暴力做法,枚举那个取到一半的数组,其余$N-1$个数组相当于$N-1$个物品,做一下背包,然后再枚举一下多余的一个数组里取了几个数,和背包结合一下出答案。
可是我们没有办法高效地从一个$N$个物品的背包得到删去里面某一个物品后剩余物品组成的背包。如果暴力做$N$次背包的话。$O(N\times N\times K)$的时间复杂度是不合格的。
然后就是这道题的神奇分治优化。
优化思路是这样的,我们将去除物品$i$的影响后剩下的背包称作$f[i]$,可以发现,$f[\frac{N}{2}+1]…f[N]$有个共同点,那就是都保留了物品$i\in [1, \frac{N}{2}]$对背包的影响,所以可以先求出物品$i\in [1, \frac{N}{2}]$组成的背包,然后再由该背包去推出$f[\frac{N}{2}+1]…f[N]$。
将上面的优化思路推广,想象成一颗线段树的形式,线段树上的某一个结点$x[l,r]$表示的就是去除物品$i\in [l,r]$的影响后的背包。递归下去时,往左儿子的背包中加入右儿子区间内的所有物品的影响,往右儿子的背包中加入左儿子区间内的所有物品的影响。递归到最后$l==r$的叶子结点时,就是我们需要的$f[i]$。
空间上,因为是类似线段树的形式,总共$4\times N$个结点,每个节点一个大小为$K$的背包,空间$O(4\times N\times K)$。
时间上,线段树总共$logN$层,在每一层中,每个物品都会跟其兄弟结点中的背包发生一次合并,因此每一层都是$N$次合并,每次合并$O(K)$,因此时间复杂度$O(logN\times N\times K)$。
1 |
|
Lucky Numbers (CF 1428 G)
咕
String Transformation (CF 1383 C)
咕
Cells Blocking (300iq contest)
咕