http://codeforces.com/contest/909/problem/C
题意:
按顺序给出n行代码的类型, 问你有几种排列方式。
解题思路:
一开始很容易想到一个n^3的DP。
dp[i][j] 表示前i行代码第i行代码有j个缩进的方案数。
如果i-1行为for 那么第i行只能是在前一行的基础上多加一个缩进。转移为O(n)
如果i-1行为s 那么 这一行可以有任意个缩进。转移为O(n^2)
然后需要优化一下,按照经验 这种DP通常使用前缀和进行优化。 然后恰好发现每一个状态dp[i][j]是由dp[i-1][0->j]转移而来,可以使用前缀和来降维。
最后的答案就是把所有的情况都加起来求和。
思路是这样,然后还可以写得更骚气一点。
#include<iostream>
#include<math.h>
#include<cstdio>
#include<string>
#include<cstring>
#define LL long long
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define x first
#define y second
using namespace std;
const int MAX=1e5+10;
long long dp[5005];
const int MOD=1e9+7;
int main() {
int n;
scanf("%d",&n);
int e=1;
char op[3];
char pre=0;
dp[1]=1;
for(int i=0;i<n;i++){
scanf("%s",op);
if(op[0]=='f'){
e++;
}else{
for(int j=1;j<=e;j++){
dp[j]=(dp[j]+dp[j-1])%MOD;
}
}
}
cout<<dp[e]<<endl;
}