Problem:
問題名 箱根駅伝

日本のお正月の風物詩に箱根駅伝があります。箱根駅伝は、各チーム 10 人の走者が中継所ごとに襷をつなぎながらゴールを目指すというものです。テレビの放送では中継所で各チームの通過順位と共に前の中継所からの順位変動が表示されます。そこで、それを見て前の中継所の各チームの通過順として考えられるものが何通りあるか答えてください。ありえた通過順の数は非常に大きくなりうるので、1,000,000,007 で割った余りで答えて下さい。

Input

入力は以下の形で与えられます

n
c1
c2
...
cn

1行目にはチーム数を表す数字 n (1 ≤ n ≤ 200) が、続く n 行には 1 位から順に前の中継所からの順位変動 ci ('D' なら順位が落ちてる、'U' なら順位が上がってる、'-' なら順位が変わってない) が書いてあります。

Output

前の中継所でありえた通過順が何通りかを、 1,000,000,007 で割ったあまりで 1 行で出力して下さい。

Sample Input 1

3
-
U
D

Output for the Sample Input 1

1

この中継所を 1 位、 2 位、 3 位で通過したチームのチーム名をそれぞれ A, B, C とすると、前の中継所の通過順として考えられるのは 1 位：チーム A, 2 位：チーム C, 3 位：チーム B の 1 通りのみです。

Sample Input 2

5
U
U
-
D
D

Output for the Sample Input 2

5

この中継所の通過順にチーム名を A, B, C, D, E とすると、前の中継所の通過順として考えられるのは {D, E, C, A, B}, {D, E, C, B, A}, {E, D, C, A, B}, {E, D, C, B, A}, {D, A, C, E, B} の5通りです。

Sample Input 3

8
U
D
D
D
D
D
D
D

Output for the Sample Input 3

1

Sample Input 4

10
U
D
U
D
U
D
U
D
U
D

Output for the Sample Input 4

608

Sample Input 5

2
D
U

Output for the Sample Input 5

0

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using static System.Math;
using System.Numerics;
static class Program{
	const int mod=(int)1e9+7;
	static void Main(){
		Sc sc=new Sc();
		var n=sc.I;
		var dp=new Mint[n+1][];
		dp[0]=new Mint[n+1];
		dp[0][0]=1;
		for(int i = 1;i<=n;i++) {
			var e=sc.S;
			dp[i]=new Mint[n+1];
			if(e=="U"){dp[i][0]=dp[i-1][0];}
			for(int j = 1;j<=i;j++) {
				if(e=="-"){dp[i][j]=dp[i-1][j-1];}
				else if(e=="U"){
					if(i>j){
						dp[i][j]+=dp[i-1][j-1]*(i-j);
						dp[i][j]+=dp[i-1][j];
					}
				}
				else{
					if(j>1){dp[i][j]=dp[i-1][j-2]*((i-1)-(j-2))*((i-1)-(j-2));}
					dp[i][j]+=dp[i-1][j-1]*((i-1)-(j-1));
				}
			}
		}
		Console.WriteLine("{0}",dp[n][n]);
	}
}
public struct Mint{
	const int mod=(int)1e9+7;
	private long d;
	public Mint(long d){this.d=d;}
	public static implicit operator Mint(long d){return new Mint(d);}
	public static explicit operator long(Mint d){return d.d;}
	public override string ToString(){return d.ToString();}
	public static Mint operator+(Mint a,long b){a.d=(a.d+b)%mod;return a;}
	public static Mint operator+(Mint a,Mint b){a.d=(a.d+b.d)%mod;return a;}
	public static Mint operator-(Mint a,long b){a.d=(mod+a.d-b)%mod;return a;}
	public static Mint operator-(Mint a,Mint b){a.d=(mod+a.d-b.d)%mod;return a;}
	public static Mint operator*(Mint a,long b){a.d=(a.d*b)%mod;return a;}
	public static Mint operator*(Mint a,Mint b){a.d=(a.d*b.d)%mod;return a;}
	public static Mint operator/(Mint a,long b){a.d=(a.d*Mi(b))%mod;return a;}
	public static Mint operator/(Mint a,Mint b){a.d=(a.d*Mi(b.d))%mod;return a;}
	private static long Mi(long a){
		a=(a+mod)%mod;
		long b=mod,u=1,v=0;
		while(b>0){
			long t=a/b;
			a-=t*b;a^=b;b^=a;a^=b;
			u-=t*v;u^=v;v^=u;u^=v;
		}
		u%=mod;
		if(u<0){u+=mod;}
		return u%mod;
	}
}

public class Sc{
	public int I{get{return int.Parse(Console.ReadLine());}}
	public long L{get{return long.Parse(Console.ReadLine());}}
	public double D{get{return double.Parse(Console.ReadLine());}}
	public string S{get{return Console.ReadLine();}}
	public int[] Ia{get{return Array.ConvertAll(Console.ReadLine().Split(),int.Parse);}}
	public long[] La{get{return Array.ConvertAll(Console.ReadLine().Split(),long.Parse);}}
	public double[] Da{get{return Array.ConvertAll(Console.ReadLine().Split(),double.Parse);}}
	public string[] Sa{get{return Console.ReadLine().Split();}}
	public object[] Oa{get{return Console.ReadLine().Split();}}
	public int[] Ia2{get{return Array.ConvertAll(("0 "+Console.ReadLine()+" 0").Split(),int.Parse);}}
	public int[] Ia3(int a){return Array.ConvertAll((a.ToString()+" "+Console.ReadLine()).Split(),int.Parse);}
	public int[] Ia3(bool a,int b,bool c,int d){return Array.ConvertAll(((a?b.ToString()+" ":"")+Console.ReadLine()+(c?" "+d.ToString():"")).Split(),int.Parse);}
	public long[] La2{get{return Array.ConvertAll(("0 "+Console.ReadLine()+" 0").Split(),long.Parse);}}
	public long[] La3(int a){return Array.ConvertAll((a.ToString()+" "+Console.ReadLine()).Split(),long.Parse);}
	public long[] La3(bool a,int b,bool c,int d){return Array.ConvertAll(((a?b.ToString()+" ":"")+Console.ReadLine()+(c?" "+d.ToString():"")).Split(),long.Parse);}
	public T[] Arr<T>(int n,Func<T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f();}return a;}
	public T[] Arr<T>(int n,Func<int,T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f(i);}return a;}
	public T[] Arr<T>(int n,Func<string[],T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f(Console.ReadLine().Split());}return a;}
	public T[] Arr<T>(int n,Func<int,string[],T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f(i,Console.ReadLine().Split());}return a;}
}