「总结」$pdf$课:$dp2$
首先发现每一条边\((i\rightarrow i+1)\)只有两种状态。
向左走或者向右走。
我们只需要记录\(dp[i][j]\)表示前\(i\)个点有\(j\)条向左的答案即可。
转移的时候应当特判\(s,t\)同时判断当前状态是否可以使得向左或者向右的边配对。
看剩下的向左或者右边是否足够即可。
将数组减下标。
这样目标就是让处理后的数组严格递增。
那么设\(dp[i][j]\)为\(a[i]=j\)时的答案。
那么
对于每一个\(i\),只有几个关键点的答案是不同的。
堆维护即可。
转化成对于任何\(a_i\)个进行操作。
那就是求:
\(\sum\limits_{j=1}^{i}x_i\leq s_i\)
的\(\{x\}\)个数。
设\(dp[i][j][k]\)为前\(i\)个时刻总和为\(j\)的\(\{x\}\)的长度为\(k\)的方案数。
\((x+y)=n\)。
所以我们设\(dp[i][0/1][j]\)为前\(i\)位中这一位为\(0/1\)的\(1\)的个数的\(j\)次方的和。
然后这是一个显然矩阵乘法的转移形式。
所以我们可以用矩阵加速转移。
如果\(c=1\),相当于每一位是独立的。
那么直接做一个数位\(dp\)即可。
如果\(c=0\),从高位向低位进行\(dp\),状态中记录更高的位有多少个是\(b^i\)即可。
仍然是一个数位\(dp\),只不过增加了一维状态。
将字符转换成数字\(0/1/2\)。
那么有解的条件即为:
原因?
分情况:
两个相同的的和必然是\(0/2/4\),那么变成和之前不同的两个不同的,也就是分别对应着\(3/2/1\)而他们是\(mod\ 3\)同余的。
两个不同的的和必然是\(1/2/3\),那么变成和之前不同的两个相同的,也就是分别对应着\(4/2/0\)而他们是\(mod\ 3\)同余的。
综上所述有解条件成立,且如此分析,解必然在不超过\(n\)步内。
将每一个满足如上条件的区间分割开。
设\(dp[i][j][k]\)表示前\(i-1\)个位置的大小已经确定的情况下,第\(i\)个位置利用\(i-n\)以内的数从\(j\)变化为\(k\)的最小代价。
统计答案的时候我们可以直接做一个取模背包。
我们只要\(dp\)出相应血量能够打出的最高怪兽数即可。
将某一个位置关于时间变化的代价写成函数。
那么我们按照\((a_i+b_i)\)给怪兽排序挨个打。
最终的答案一定是一个子序列。
可以发现分层\(dp\)的话。
答案\(i\)的最优决策集合\(S_i\),必然有\(S_i\subseteq S_{i+1}\)。
典型的序列插入平移维护\(dp\)值。
那么我们用个平衡树搞一下就可以了。
可以把最终答案转化为给每个环定向的方案。
同时条型可以看作两个点的环,那么方向仅有一个,对答案的贡献刚好是1.
给非障碍点之间连边。
转化题意为环覆盖方案。
我们把每个点拆成\(x,y\)连边\(i\rightarrow j\)变成\(x_i\rightarrow y_j\),
这样一组环覆盖,相当于是一组完美匹配。
因为环上的点都只有一条出边和一条入边。
那么我们搞一个状压\(dp\)。
设\(dp[i][S]\)表示右侧的前\(i\)个点已经和左侧的\(S\)集合中的点完美匹配的方案数。