作者:HJL--希 | 来源:互联网 | 2023-10-10 15:26
F-VasyaandArraydp[i][j]表示用了前i个数字并且最后一个数字是j的方案数。dp[i][j]sumdp[i-1][j],这样的话会有不合法的方案算进去,而且不合法
F - Vasya and Array
dp[ i ][ j ] 表示用了前 i 个数字并且最后一个数字是 j 的方案数。
dp[ i ][ j ] = sumdp [i - 1 ][ j ], 这样的话会有不合法的方案算进去,而且不合法的方案只有 i - len + 1 到 i 这一段相同才会
出现, 所以如果 i - len + 1 到 i 可以变成一样的话要减去 sumdp[ i - len ] - dp[ i - len ][ j ]
#include
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair
#define PLI pair
#define PII pair
#define SZ(x) ((int)x.size())
#define ull unsigned long long
#define x first
#define y second
using namespace std;
const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-8;
int n, k, len, a[N];
int dp[N][101], sum[N], cnt[N][101];
inline void add(int &a, int b) {
a += b; if(a >= mod) a -= mod;
}
int main() {
scanf("%d%d%d", &n, &k, &len);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= k; j++)
cnt[i][j] = cnt[i-1][j] + (a[i]==j || a[i]==-1);
sum[0] = 1;
for(int i = 1; i <= n; i++) {
if(i < len) {
if(~a[i]) {
add(dp[i][a[i]], sum[i-1]);
} else {
for(int j = 1; j <= k; j++)
add(dp[i][j], sum[i-1]);
}
} else {
if(~a[i]) {
add(dp[i][a[i]], sum[i-1]);
if(cnt[i][a[i]]-cnt[i-len][a[i]] == len) {
add(dp[i][a[i]], mod-(sum[i-len]-dp[i-len][a[i]]+mod)%mod);
}
} else {
for(int j = 1; j <= k; j++) {
add(dp[i][j], sum[i-1]);
if(cnt[i][j]-cnt[i-len][j]==len) {
add(dp[i][j], mod-(sum[i-len]-dp[i-len][j]+mod)%mod);
}
}
}
}
for(int j = 1; j <= k; j++)
add(sum[i], dp[i][j]);
}
printf("%d\n", sum[n]);
return 0;
}
/*
*/
Educational Codeforces Round 56 (Rated for Div. 2) F - Vasya and Array dp好题