题意略。
思路:
开始的时候,定义dp[i]:当前行在第i行,i~n有多少种排列方式,如果i为f,那么dp[i] = dp[i + 1],因为第i + 1条语句只能放在f后且向右缩进一位;
如果i为s,那么dp[i]还与第i行的缩进有关。因此我们增加缩进这个状态。
定义dp[i][j]:当前行在第i行,缩进为j,i~n有多少种排列方式。
当i为s的时候,dp[i][j] = sum(dp[i + 1][k]) 1 <= k <= j;
当j为f的时候,dp[i][j] = dp[i + 1][j + 1];
详见代码:
#includeusing namespace std;typedef long long LL;const LL mod = 1000000000 + 7;const int maxn = 5005;LL dp[2][maxn];int n;string str;int main(){ std::ios::sync_with_stdio(false); cin>>n; string temp; for(int i = 0;i < n;++i){ cin>>temp; str += temp; } memset(dp,-1,sizeof(dp)); for(int i = 0;i <= n;++i) dp[n & 1][i] = 1; for(int i = n - 1;i >= 1;--i){ LL cur = 0; for(int j = 0;j <= i - 1;++j){ if(str[i - 1] == 's'){ cur += dp[(i + 1) & 1][j]; cur %= mod; dp[i & 1][j] = cur; } else{ dp[i & 1][j] = dp[(i + 1) & 1][(j + 1)]; } } } cout< <