Codeforces Round #455 (Div. 2)
C. Python Indentation
题意:python 里面,给出 n 个 for 循环或陈述语句,‘f‘ 里面必须要有语句。按 python 缩进的方式组合成合法的程序,问有多少种可能方案。
tags: dp
dp[i][j] 表示第 i 个语句缩进为 j 时的可能方案数, 转移:
1】 如果第 i 个是 ‘f‘ , 则第 i+1 个肯定要比第 i 个多缩进一个单位,即 dp[i+1][j] = dp[i][j]。
2】如果第 i 个是 ‘s‘ ,则第 i+1 个可以属于前面任何一个 for 循环,也就是说第 i+1 个的缩进要 <= 第 i 个的缩进,即 dp[i+1][j] = dp[i][k], j<=k<=n 。
复杂度 O(n^2)。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f #define MP make_pair #define PB push_back #define fi first #define se second typedef long long ll; const int N = 5005, mod = 1e9+7; int n; ll dp[N][N]; char ch; int main() { scanf("%d", &n); dp[1][0] = 1; rep(j,1,n) dp[1][j]=0; rep(i,1,n-1) { scanf("%*c%c", &ch); if(ch==‘f‘) { dp[i+1][0] = 0; rep(j,0,n) { dp[i+1][j+1] = dp[i][j]; } } else { ll sum = 0; per(j,n,0) { sum += dp[i][j]; sum %= mod; dp[i+1][j] = sum; } } } scanf("%*c%c", &ch); ll ans = 0; rep(j,0,n) ans += dp[n][j], ans %= mod; printf("%lld\n", ans); return 0; }