标签:并且 col href http 相同 https namespace force com
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<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #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好题
标签:并且 col href http 相同 https namespace force com
原文地址:https://www.cnblogs.com/CJLHY/p/10184390.html