首先发现每一条边((i
ightarrow i+1))只有两种状态。
向左走或者向右走。
我们只需要记录(dp[i][j])表示前(i)个点有(j)条向左的答案即可。
转移的时候应当特判(s,t)同时判断当前状态是否可以使得向左或者向右的边配对。
看剩下的向左或者右边是否足够即可。
将数组减下标。
这样目标就是让处理后的数组严格递增。
那么设(dp[i][j])为(a[i]=j)时的答案。
那么
对于每一个(i),只有几个关键点的答案是不同的。
堆维护即可。
转化成对于任何(a_i)个进行操作。
那就是求:
(sumlimits_{j=1}^{i}x_ileq 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_isubseteq S_{i+1})。
典型的序列插入平移维护(dp)值。
那么我们用个平衡树搞一下就可以了。
可以把最终答案转化为给每个环定向的方案。
同时条型可以看作两个点的环,那么方向仅有一个,对答案的贡献刚好是1.
给非障碍点之间连边。
转化题意为环覆盖方案。
我们把每个点拆成(x,y)连边(i
ightarrow j)变成(x_i
ightarrow y_j),
这样一组环覆盖,相当于是一组完美匹配。
因为环上的点都只有一条出边和一条入边。
那么我们搞一个状压(dp)。
设(dp[i][S])表示右侧的前(i)个点已经和左侧的(S)集合中的点完美匹配的方案数。