有一个长度为
n
n
n的的数列,
a
i
a_i
ai的值域只有
k
k
k个元素。
一个数列有一些数字已经填上。现在要求数列连续的数字长度不能超过
l
l
l,问所有不同的数列的个数有多少个。
1.考虑所有的数字都没填上。设
d
p
[
i
]
[
j
]
[
s
]
dp[i][j][s]
dp[i][j][s]为第
i
i
i个位置填入第
j
j
j种颜色且已经有连续的
s
s
s个数字的方案数。显然:
那么:
d
p
[
i
]
[
j
]
[
s
]
=
d
p
[
i
−
1
]
[
j
]
[
s
−
1
]
−
[
s
⩾
l
−
1
]
(
∑
p
=
1
∞
(
∑
t
=
1
k
d
p
[
i
−
l
+
1
]
[
t
]
[
p
]
−
d
p
[
i
−
l
+
1
]
[
j
]
[
p
]
)
)
,
2
⩽
s
⩽
l
−
1
,
d
p
[
i
]
[
j
]
[
s
]
=
∑
1
⩽
t
⩽
k
,
j
≠
t
∑
p
=
1
∞
d
p
[
i
−
1
]
[
t
]
[
p
]
,
s
=
1
d
p
[
i
]
[
j
]
[
s
]
=
0
,
s
⩾
l
.
dp[i][j][s]=dp[i-1][j][s-1] -[s\geqslant l-1](\sum_{p=1}^{\infty}(\sum_{t=1}^k dp[i-l+1][t][p]-dp[i-l+1][j][p])),2\leqslant s \leqslant l-1,\\ dp[i][j][s]=\sum_{1\leqslant t\leqslant k,j\neq t}\sum_{p=1}^{\infty}dp[i-1][t][p],s=1\\ dp[i][j][s]=0,s\geqslant l.
dp[i][j][s]=dp[i−1][j][s−1]−[s⩾l−1](p=1∑∞(t=1∑kdp[i−l+1][t][p]−dp[i−l+1][j][p])),2⩽s⩽l−1,dp[i][j][s]=1⩽t⩽k,j̸=t∑p=1∑∞dp[i−1][t][p],s=1dp[i][j][s]=0,s⩾l.
求和得:
∑
p
=
1
s
d
p
[
i
]
[
j
]
[
p
]
=
∑
p
=
1
∞
∑
t
=
1
k
d
p
[
i
−
1
]
[
j
]
[
p
]
−
[
s
⩾
l
−
1
]
(
∑
p
=
1
∞
∑
t
=
1
k
d
p
[
i
−
l
+
1
]
[
t
]
[
p
]
−
∑
p
=
1
∞
d
p
[
i
−
l
+
1
]
[
j
]
[
p
]
)
\sum_{p=1}^{s}dp[i][j][p]=\sum_{p=1}^{\infty}\sum_{t=1}^kdp[i-1][j][p]-[s\geqslant l-1](\sum_{p=1}^{\infty}\sum_{t=1}^k dp[i-l+1][t][p]-\sum_{p=1}^{\infty}dp[i-l+1][j][p])
p=1∑sdp[i][j][p]=p=1∑∞t=1∑kdp[i−1][j][p]−[s⩾l−1](p=1∑∞t=1∑kdp[i−l+1][t][p]−p=1∑∞dp[i−l+1][j][p])
因为具有规整性,并且考虑到
d
p
[
i
]
[
j
]
[
s
]
=
d
p
[
i
−
1
]
[
j
]
[
s
−
1
]
dp[i][j][s]=dp[i-1][j][s-1]
dp[i][j][s]=dp[i−1][j][s−1],
所以令
a
v
a
[
i
]
[
j
]
=
∑
p
=
1
∞
d
p
[
i
]
[
j
]
[
p
]
,
s
u
m
[
i
]
=
∑
i
=
1
k
a
v
a
[
i
]
[
j
]
\displaystyle ava[i][j]=\sum_{p=1}^{\infty}dp[i][j][p],sum[i]=\sum_{i=1}^k ava[i][j]
ava[i][j]=p=1∑∞dp[i][j][p],sum[i]=i=1∑kava[i][j],得:
a
v
a
[
i
]
[
j
]
=
s
u
m
[
i
−
1
]
−
[
max
a
v
a
l
e
n
j
⩾
l
−
1
]
(
s
u
m
[
i
−
l
+
1
]
−
a
v
a
[
i
−
l
+
1
]
)
,
i
=
1
,
2
,
…
,
n
ava[i][j]=sum[i-1]-[\max avalen_j\geqslant l-1](sum[i-l+1]-ava[i-l+1]),i=1,2,\dots,n
ava[i][j]=sum[i−1]−[maxavalenj⩾l−1](sum[i−l+1]−ava[i−l+1]),i=1,2,…,n
其中
max
a
v
a
l
e
n
j
\max avalen_j
maxavalenj是指当前可能达到的最大连续后缀长度。
2.考虑有的数字已经填上。显然这时候,如果
j
=
a
[
i
]
j=a[i]
j=a[i],则可以继续转移,但是只有一种可能。如果
j
≠
a
[
i
]
j\neq a[i]
j̸=a[i],也可以继续转移,但是
max
a
v
a
l
e
n
j
\max avalen_j
maxavalenj被隔断,所以重新计算。
#include <cstdio>
#include <iostream>
const int N=100005,K=105;
const long long mod=998244353LL;
int a[N];
long long dp[N],ava[N][K],len[K],bad[K];
int main(){
int n,k,l;
scanf("%d%d%d",&n,&k,&l);l--;
if(!l){
puts("0");
return 0;
}
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
dp[0]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=k;j++){
if(a[i]==j||a[i]==-1){
ava[i][j]=(dp[i-1]+mod-bad[j])%mod;
len[j]++;
if(len[j]>=l){
bad[j]=(dp[i-l]+mod-ava[i-l][j])%mod;
}
dp[i]+=ava[i][j];
if(dp[i]>=mod)dp[i]-=mod;
}else{
len[j]=bad[j]=0;
}
}
}
printf("%I64d\n",dp[n]);
//std::system("pause");
}