首先将字符串
S
=
x
y
S=xy
S=xy变换为
y
x
yx
yx,等价于将字符串
S
S
S循环右移或左移(读者可以自己举例子尝试一下)
那么,只要
T
T
T是
S
S
S的循环同构串,当
S
!
=
T
S != T
S!=T时,
S
S
S只要经过
1
1
1次操作即可变换为
T
T
T;当
S
=
=
T
S == T
S==T时,
S
S
S经过
0
0
0次操作即可变换为
T
T
T
现在,称字符串循环左移
(
j
+
n
)
%
n
(j+n)\%n
(j+n)%n个位置得到的新字符串称为字符串
j
j
j
定义
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]为字符串S经过
i
i
i次操作后,得到字符串
j
j
j的操作方案。其中,
0
≤
i
≤
k
,
0
≤
j
≤
n
−
1
0 \le i \le k, 0 \le j \le n-1
0≤i≤k,0≤j≤n−1
显然字符串
s
s
s经过
1
1
1次操作可以变换到任意字符串
x
x
x,除非
s
=
=
x
s==x
s==x。同样地,任意字符串
x
x
x也可以经过一次操作变换到字符串
j
j
j,除非
j
=
=
x
j==x
j==x。
那么有
d
p
[
i
]
[
j
]
=
s
u
m
(
d
p
[
i
−
1
]
[
x
]
)
,
0
≤
x
≤
n
−
1
a
n
d
x
≠
j
dp[i][j]=sum(dp[i-1][x]), 0 \le x \le n-1 \, and \; x \neq j
dp[i][j]=sum(dp[i−1][x]),0≤x≤n−1andx=j
然后空间压缩即可。否则
n
∗
k
n*k
n∗k的数据会爆内存
时间复杂度
O
(
n
k
)
O(nk)
O(nk) ,空间复杂度
O
(
n
)
O(n)
O(n)
压缩
i
i
i这个维度的代码:
#include"bits/stdc++.h"usingnamespace std;constexprint MOD =1e9+7;using LL =longlong;
string S, T;int k;
LL d[2][1005];
LL sum[2];int n;intmain(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);while(cin >> S >> T >> k){memset(d,0,sizeof d);memset(sum,0,sizeof sum);
n = S.size();
d[0][0]=1;
sum[0]=1;for(int i =1; i <= k;++i){
sum[i &1]=0;for(int j =0; j < n;++j){
d[i &1][j]=(sum[(i +1)&1]+ MOD - d[(i +1)&1][j])% MOD;
sum[i &1]=(sum[i &1]+ d[i &1][j])% MOD;}}
LL ans =0;for(int i =0; i < n;++i){
string tmp = S.substr(i)+ S.substr(0, i);if(tmp == T){
ans =(ans + d[k &1][i])% MOD;}}
cout << ans << endl;}}/*
aaca
caaa
2
ac
ca
2
*/
另一种思路
首先计算出
S
S
S经过1次变换或0次变换到达
T
T
T的操作方案个数。那么这也是任意一个字符串变换为T的方案个数。记该操作方案个数为
c
n
t
cnt
cnt。注意cnt中可能包含自身变换到自身的情况。
定义
d
p
[
i
]
[
0
]
dp[i][0]
dp[i][0]为经过
i
i
i次操作之后,无法到达
T
T
T的个数。
d
p
[
i
]
[
1
]
dp[i][1]
dp[i][1]为经过
i
i
i次操作之后,到达
T
T
T的个数
那么有
d
p
[
i
]
[
0
]
=
d
p
[
i
−
1
]
[
0
]
×
(
n
−
c
n
t
−
1
)
+
d
p
[
i
−
1
]
[
1
]
×
(
n
−
c
n
t
)
d
p
[
i
]
[
1
]
=
d
p
[
i
−
1
]
[
0
]
×
c
n
t
+
d
p
[
i
−
1
]
[
1
]
×
(
c
n
t
−
1
)
dp[i][0]=dp[i-1][0] \times (n-cnt-1)+dp[i-1][1] \times (n-cnt) \\ dp[i][1]=dp[i-1][0] \times cnt + dp[i-1][1] \times (cnt-1)
dp[i][0]=dp[i−1][0]×(n−cnt−1)+dp[i−1][1]×(n−cnt)dp[i][1]=dp[i−1][0]×cnt+dp[i−1][1]×(cnt−1)