Codeforces 1093F. Vasya and Array (DP) 日付: 12月 19, 2018 リンクを取得 Facebook × Pinterest メール 他のアプリ [Problem - 1093F - Codeforces](https://codeforces.com/contest/1093/problem/F) ## Problem Given an array AAA of nnn integers, each element is each -1 or between 1 and kkk. You change each -1 into a number between 1 and kkk, and the result array does not contain a range of length lenlenlen of the same number. Calculate how many ways to do this. **Constraints:** 1≤n≤105, 1≤k≤100, 1≤len≤n1\le n \le 10^5,\ 1 \le k \le 100,\ 1 \le len \le n1≤n≤105, 1≤k≤100, 1≤len≤n ## Solution If we define fi,j,kf_{i,j,k}fi,j,k as the number of ways to fill A[1,i]A[1,i]A[1,i] with the last element is jjj and the length the suffix of the same number is kkk, it seems easy to solve. However, lenlenlen is too large and we cannot include it in dp state. Let's define: * fi,jf_{i,j}fi,j - The number of valid ways to fill A[1⋯i]A[1\cdots i]A[1⋯i] with the last element is jjj * sis_isi - The number of valid ways to fill A[1⋯i]A[1\cdots i]A[1⋯i]. si=∑j=1kfi,js_i = \sum_{j=1}^k f_{i,j}si=∑j=1kfi,j * pi,jp_{i,j}pi,j - The rightmost position of a number jjj in A[1⋯i]A[1\cdots i]A[1⋯i]. Initially, if Ai=jA_i=jAi=j or Ai=−1A_i=-1Ai=−1, fi,j=si−1f_{i,j} = s_{i-1}fi,j=si−1. But when these conditions are met: * i>=leni >= leni>=len. * All elements in A[i−len+1⋯i]A[i-len+1 \cdots i]A[i−len+1⋯i] are either -1 or jjj (this can be checked by ppp) There exist cases when A[i−len+1⋯i]A[i-len+1 \cdots i]A[i−len+1⋯i] are all filled to jjj (notice that A[i−len]A[i-len]A[i−len] couldn't be jjj because these cases are already substracted at position i−1i-1i−1). The number of such bad cases are si−len−fi−len,js_{i-len}-f_{i-len,j}si−len−fi−len,j ## Code ```c++ #include <bits/stdc++.h> using namespace std; #define FI(i,a,b) for(int i=(a);i<=(b);++i) constexpr int madd(int x, int y, int m) { return (0LL + x + y + m + m) % m; } const int N = 1e5 + 5, M = 998244353; int n, k, len, C[N], F[N][105], P[N][105], S[N]; int main() { scanf("%d%d%d", &n, &k, &len); FI(i, 1, n) scanf("%d", C + i); FI(i, 1, n) FI(j, 1, k) { P[i][j] = P[i - 1][j]; if (C[i] == j) P[i][j] = i; } S[0] = 1; FI(i, 1, n) FI(j, 1, k) { if (C[i] != -1 && C[i] != j) F[i][j] = 0; else { F[i][j] = S[i - 1]; bool ok = true; if (i < len) ok = false; FI(jj, 1, k) if (jj != j && P[i][jj] > i - len) ok = false; if (ok) F[i][j] = madd(F[i][j], madd(-S[i - len], F[i - len][j], M), M); } S[i] = madd(S[i], F[i][j], M); } printf("%d\n", S[n]); } ``` コメント
コメント
コメントを投稿