假设机器某次出发到回到 0 0 0的过程中收集了 a a a个垃圾,最优过程必然是先走到最远的垃圾处拿起来,再在往回走的过程中依次拿起剩下 a − 1 a-1 a−1个垃圾。
设 f ( i , j ) f(i,j) f(i,j)表示从左到右第 i i i个垃圾在同一组中在第 j j j次被拿起的花费:
f ( i , j ) = { 5 x i + 2 X ( j = 1 ) ( 2 j − 1 ) x i + X ( j > 1 ) f(i,j)=\left\{\begin{matrix} 5x_i+2X\ \ (j=1)\\ (2j-1)x_i+X\ \ (j>1) \end{matrix}\right. f(i,j)={5xi+2X (j=1)(2j−1)xi+X (j>1)
考虑枚举划分出的组数 k k k,显然最远的 n k \frac nk kn作为每组内最先拿的垃圾最优,于是每相邻 n k \frac nk kn个分别分到每个组。算一下总贡献取 min \min min即可。复杂度是调和级数的 n ln n n\ln n nlnn
可行解的图一定是一个环,满足环上每一个点都有 A , B A,B A,B的出边。
所以类似于拓扑排序,每次删去没有 A / B A/B A/B出边的点即可。
构造 m o d = 1 mod= 1 mod=1的情况:
如果没有限制所有位置数不同,可以将网格黑白染色,所有黑格值为 n + 1 n+1 n+1,白格为 n n n。
(好吧我知道其实更容易想到 2 , 3 , 4 , . . . 2,3,4,... 2,3,4,...,但是要贪心在更小的权值区间内取得更大的矩阵…)
加上限制后同理,假设黑格比它相邻的白格都大,则值为它相邻的白格值的 l c m + 1 lcm +1 lcm+1,且所有黑格之间互不影响。
用不同的质数填充所有正/反对角线即可,每个白格的值为两条对角线上质数的乘积。
把 a a a看做 1 1 1, b b b看做 2 2 2,序列在 ( m o d 3 ) \pmod 3 (mod3)意义下保持不变。
求序列的前缀和 S S S,那么可以构造出的所有序列的前缀和都是 S S S的子序列,DP即可。
把每个 S [ i ] = S [ n ] ( i < n ) S[i]=S[n](i<n) S[i]=S[n](i<n)且后面存在两个相邻字符相同的情况或者的 f [ i ] f[i] f[i]计入答案,最后 + f [ n ] +f[n] +f[n]即可。
code from DZYO
#include
using namespace std;
const int N=1e5+50, mod=1e9+7;
inline void add(int &x,int y) {x=(x+y>=mod) ? (x+y-mod) : (x+y);}
char t[N];
int n,ans,s[N],f[N],pre[N][3],fir[N];
int main() {
scanf("%s",t+1); n=strlen(t+1);
for(int i=1;i<=n;i++) s[i]=(s[i-1]+t[i]-'a'+1)%3;
pre[0][0]=pre[0][1]=pre[0][2]=-1;
for(int i=1;i<=n;i++) {
pre[i][0]=pre[i-1][0];
pre[i][1]=pre[i-1][1];
pre[i][2]=pre[i-1][2];
pre[i][s[i-1]]=i-1;
}
for(int i=1;i<=n;i++) {
fir[i]=fir[i-1];
if(t[i]==t[i-1]) fir[i]=i;
}
f[0]=1;
for(int i=1;i<=n;i++) {
int pos=fir[i]-1;
f[i]=f[i-1];
int val=(t[i]=='a') ? 2 : 1;
if(~pos) {
pos=pre[pos][(s[i]-val+3)%3];
if(~pos) add(f[i],f[pos]);
}
if(!s[i] && i!=n) add(f[i],1);
}
if(!fir[n]) for(int i=1;i<n;i++) if(!s[i]) add(f[n],mod-1);
cout<<f[n]<<'\n';
}
分两种情况讨论:
A → B A\to B A→B存在不动点。 O ( n ) O(n) O(n)枚举不动点 i i i,以 i i i为根,对于点 x ( x ≠ i ) x(x\neq i) x(x̸=i),若 x x x在 A A A中的父结点为 y y y,在 B B B中的父结点为 z ( y ≠ z ) z(y\neq z) z(y̸=z),设其修改时间为 t x t_x tx,存在以下关系:
拓扑排序判断是否有解。
A → B A\to B A→B不存在不动点。 O ( n 3 ) O(n^3) O(n3)枚举第一次选择的叶节点和改变后指向的点,在第一次操作后强制其为不动点拓扑排序判断。
两种情况都尝试一下,复杂度 O ( n 3 T ) O(n^3T) O(n3T)