#include #ifdef AZN #include "Azn.cpp" #else #define pln(...) #define dbgln(...) #endif using namespace std; typedef long long ll; template struct IntMod { IntMod() : val_(0) {} IntMod(long long x) : val_((int) (x % MOD)) { if (val_ < 0) val_ += MOD; } IntMod& operator+=(const IntMod& x) { val_ += x.val_; if (val_ >= MOD) val_ -= MOD; return *this; } IntMod operator+(const IntMod& x) const { IntMod res(*this); return res += x; } IntMod& operator-=(const IntMod& x) { val_ -= x.val_; if (val_ < 0) val_ += MOD; return *this; } IntMod operator-(const IntMod& x) const { IntMod res(*this); return res -= x; } IntMod& operator*=(const IntMod& x) { val_ = (int) ((long long) (val_) * x.val_ % MOD); return *this; } IntMod operator*(const IntMod& x) const { IntMod res(*this); return res *= x; } IntMod& operator/=(const IntMod& x) { return *this *= x.inv(); } IntMod operator/(const IntMod& x) const { IntMod res(*this); return res /= x; } IntMod operator-() const { IntMod res(*this); if (res.val_ != 0) res.val_ = MOD - res.val_; return res; } IntMod power(int expon) const { IntMod ans, temp(*this); ans.val_ = 1; for (; expon > 0; expon >>= 1) { if (expon & 1) ans *= temp; temp *= temp; } return ans; } IntMod inv() const { return power(MOD - 2); } int get() const { return val_; } friend ostream& operator<<(ostream& out, const IntMod& x) { return out << x.val_; } bool operator==(const IntMod& x) const { return val_ == x.val_; } bool operator!=(const IntMod& x) const { return val_ != x.val_; } private: int val_; }; typedef IntMod<1000000007> Int; const int MAX = 1201; Int dp[MAX][MAX]; // prefix, open lists Int fact[MAX], ifact[MAX]; bool sorted[MAX][MAX]; int perm[MAX]; Int ways(int n, int k) { return fact[n] * ifact[n - k]; } void solve(int test_num) { (void) test_num; ifact[0] = fact[0] = 1; for (int i = 1; i < MAX; ++i) { fact[i] = fact[i - 1] * i; ifact[i] = Int(1) / fact[i]; } int N; cin >> N; for (int i = 1; i <= N; ++i) cin >> perm[i]; memset(sorted, false, sizeof(sorted)); for (int i = 1; i <= N; ++i) { sorted[i][i] = true; for (int j = i + 1; j <= N; ++j) if (perm[j] < perm[j - 1]) break; else sorted[i][j] = true; } memset(dp, 0, sizeof(dp)); for (int i = 1; i <= N; ++i) { if (sorted[1][i]) dp[i][i] = 1; for (int nx = 1; i + nx <= N; ++nx) { if (!sorted[i + 1][i + nx]) continue; for (int open = nx; open <= i; ++open) dp[i + nx][nx] += dp[i][open] * ways(open, nx); } } const Int res = accumulate(dp[N], dp[N] + N + 1, Int()); cout << res.get() << endl; } void init() { } int main() { #ifdef AZN const auto start_time = chrono::system_clock::now(); freopen("/Users/yfhuang/FHC_2017/input.txt", "r", stdin); #endif ios::sync_with_stdio(false); cin.tie(nullptr); srand(1223); init(); int tests = 1; // scanf("%d", &tests); // cin >> tests; for (int test = 1; test <= tests; ++test) { solve(test); } #ifdef AZN cerr << "Took: " << ((chrono::system_clock::now() - start_time).count() / 1e6) << " s" << endl; #endif return 0; }