CF 909C Python Indentation

题目描述

https://codeforces.com/problemset/problem/909/C

Solution

我们令 $dp$ 状态为 $f[i][j]$ 表示当前是第 $i$ 个,没有缩进的有 $j$ 行

不妨假设当前的 $for$ 与上个 $for$ 直接有 $k$ 个 $s$

那么我们注意到我们可以将若干个没有缩进的行并入当前 $for$ 中,显然方案数不会重复

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <cstdio>
#include <algorithm>
#define maxn 5010
#define ll long long
using namespace std;

const int p = 1000000007;

int n;

int a[maxn], A[maxn];

int f[maxn][maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);

cin >> n;
for (int i = 1; i <= n; ++i) {
char s[4]; cin >> s + 1;
if (s[1] == 'f') A[i] = 1;
} int cnt = 0;
for (int i = n, w = 0; i; --i)
if (A[i]) a[++cnt] = w, w = 0;
else ++w;
reverse(a + 1, a + cnt + 1); f[cnt + 1][0] = 1;
for (int i = cnt; i; --i) {
for (int j = 1; j <= n; ++j)
for (int k = 1; k <= min(a[i], j); ++k)
f[i][j] = (f[i][j] + f[i + 1][j - k]) % p;
for (int j = n, sum = 0; j; --j) {
sum = (sum + f[i + 1][j]) % p;
f[i][j] = (f[i][j] + sum) % p;
}
}
int ans = 0;
for (int i = 0; i <= n; ++i) ans = (ans + f[1][i]) % p;
cout << ans << "\n";
return 0;
}