AtCoder DP Contest
AtCoder DP Contest
A
\(f[i]\) 表示跳到 \(i\) 的最小花费。
\(f[i]=\min(f[i-2]+abs(h[i]-h[i-2]),f[i-1]+abs(h[i]-h[i-1])\)
初值 \(f[1]=0,f[2]=abs(h[2]-h[1])\),答案为 \(f[n]\)。
B
\(f[i]\) 表示跳到i的最小花费。
从 \(1-k\) 穷举 \(j\),\(f[i]=\min(f[i-j]+abs(h[i]-h[i-j]))\)
答案为 \(f[n]\)。
C
\(fa[i]\) 表示第 \(i\) 天做 \(a\) 的最大快乐质数。
\(fb[i]\) 表示第 \(i\) 天做 \(b\) 的最大快乐质数。
\(fc[i]\) 表示第 \(i\) 天做 \(c\) 的最大快乐质数。
\(fa[i]=\max(fb[i-1],fc[i-1])+a[i]\)
\(fb[i]=\max(fa[i-1],fc[i-1])+b[i]\)
\(fc[i]=\max(fa[i-1],fb[i-1])+c[i]\)
D
背包,\(f[i][j]\) 表示前 \(i\) 个物品总体积不超过 \(j\) 的最大价值
\(f[i][j]=\max(f[i-1][j],f[i-1][j-w[i]]+val[i])\)
可以用滚动数组滚掉一维。
E
\(w\) 太大了,所以我们需要改变状态的含义。\(f[i][j]\) 代表前 \(i\) 个物品价值为 \(j\) 的最小体积。
\(f[i][j]=\min(f[i-1][j],f[i-1][j-v[i]]+w[i])\)
仍然可以滚动数组。
F
LCS。先考虑只计算长度的情况。
\(f[i][j]\) 表示 \(s\) 前 \(i\) 位,\(t\) 前 \(j\) 位的最长 LCS 长度。
\(s[i]=t[j]\) 时,\(f[i][j]=\max\{f[i][j],f[i-1][j-1]+1\}\)
否则,\(f[i][j]=\max\{f[i-1][j],f[i][j-1]\}\)
原题要求输出方案,用 string 记录一下即可,但是貌似需要滚动数组。
G
图上 dp。运用拓扑排序。
\(f[v]=\max\{f[u]\}+1(u\to v)\)
H
简单的 dp。
如果 \(a[i][j]=\)'#',\(f[i][j]=0\)
否则,\(f[i][j]=f[i-1][j]+f[i][j-1]\)
I
概率 dp。\(f[i][j]\) 表示前 \(i\) 个硬币 \(j\) 枚朝上的概率。
\(f[i][j]=f[i-1][j-1]\times p[i]+f[i-1][j]\times(1-p[i])\)
J
期望 dp。\(f[i][j][k]\) 表示 \(1\) 个寿司的有 \(i\) 盘,\(2\) 个寿司的有 \(j\) 盘,\(3\) 个寿司的有 \(k\) 个,全吃完的期望次数。
转移方程如下,为了避免子问题没穷举到的问题,改变了外重循环的顺序。当然也可以记忆化搜索。
for(int k=0;k<=n;++k)
for(int j=0;j<=n;++j)
for(int i=0;i<=n;++i)
{
if(i+j+k)f[i][j][k]=1.0*n/(i+j+k);
if(i)f[i][j][k]+=f[i-1][j][k]*i/(i+j+k);
if(j)f[i][j][k]+=f[i+1][j-1][k]*j/(i+j+k);
if(k)f[i][j][k]+=f[i][j+1][k-1]*k/(i+j+k);
}
K
博弈 dp。\(f[i]\) 表示省 \(i\) 先手是否能赢。
转移:\(f[i]=!f[i-a[j]]\)
L
区间 dp。\(f[i][j]\) 表示在 \(i-j\) 区间内能取到的最大值。
转移:\(f[i][j]=\sum\limits_{x=i}^ja_x-\min(f[i+1][j],f[i][j-1])\)
M
前缀和优化 dp。
\(f_{i,j}\) 表示前 \(i\) 个人分到 \(j\) 颗糖的方案数。
可以前缀和优化。
N
区间 dp。枚举中间点。
\(f[i][j]=\min(f[i][j],f[i][k]+f[k+1][j]+sum[j]-sum[i-1])\)
O
状压 dp,\(f[i][s]\) 表示前 \(i\) 个男人匹配的女人的状态压缩为 \(s\) 的方案数。
考虑到 \(i\) 可以由 \(s\) 推出,所以可以省略第一维。
转移枚举男人与那个女人配对即可。
\(f[s]+=f[s-2^{j-1}]\)
P
树形 dp,\(f[i][0/1]\) 表示以 \(i\) 为根的子树 \(i\) 的颜色为白/黑的方案数。
f[x][0]=f[x][0]*(f[v][0]+f[v][1])%mod;
f[x][1]=f[x][1]*f[v][0]%mod;
Q
树状数组优化 dp。
\(f_i\) 表示以 \(i\) 结尾的答案。
考虑到答案都在一区间内,问题转化为区间最大值,可以使用树状数组优化。
R
矩阵快速幂优化 dp。
\(f[i][j][k]\) 表示从 \(i\) 到 \(j\) 走 \(k\) 步的方案数,发现每次转移都是矩阵相乘,初始矩阵为 \(A\),进行 \(k\) 次转移之后的矩阵即位 \(A^k\),进行矩阵快速幂即可。
S
数位 dp,设 \(f[len][pre][0/1]\) 表示还有 \(len\) 位需要填,之前数字和模 \(d\) 等于 \(pre\),当前填的数字贴不贴上界。转移时枚举当前为填的是什么,需要分类讨论。复杂度即为 \(\mathcal O(10{\rm len}(K)D)\)。
T
前缀和优化 dp,设 \(f[i][j]\) 表示第 \(i\) 位填的数字在前 \(i\) 位中是第 \(k\) 小的方案数。转移时根据大小于号穷举第 \(i-1\) 位是第几小,需要前缀和优化,复杂度 \(\mathcal O(n^2)\)。
U
状压 dp,设 \(f_i\) 表示当前集合为 \(i\) 时的最大得分。转移时枚举子集,即枚举当前集合是由哪两个子集构成的。
可以的出如下转移方程:
时间复杂度为 \(O(2^nn^2+3^n)\),分别来自 求集合不分成两部分的得分 和 穷举子集。

浙公网安备 33010602011771号