#include #define FOR(i,n) for(int i=0;i<(n);++i) #define FORU(i,j,k) for(int i=(j);i<=(k);++i) #define FORD(i,j,k) for(int i=(j);i>=(k);--i) #define error(args...) { vector _v = split(#args, ','); err(_v.begin(), args); } using namespace std; using lli = long long int; using pll = pair; string TYPE(int*) { return "%d"; } string TYPE(lli*) { return "%lld"; } string TYPE(char*) { return "%c"; } void RD() {} template void RD(T* v, Args... args) { scanf((" " + TYPE(v)).c_str(), v); RD(args...); } void PR(bool nl = true) { if(nl) printf("\n"); } template void PR(bool nl, T v, Args... args) { printf((TYPE(&v) + " ").c_str(), v); PR(nl, args...); } template void PR(Args... args) { PR(true, args...); } vector split(const string& s, char c) { vector v; stringstream ss(s); string x; while (getline(ss, x, c)) v.emplace_back(x); return move(v); } void err(vector::iterator) {} template void err(vector::iterator it, T a, Args... args) { cerr << it -> substr((*it)[0] == ' ', it -> length()) << " = " << a << '\n'; err(++it, args...); } const long long int oo = 1000*1000*1000; struct Coord { int x, y; Coord(int x = 0, int y = 0) : x(x), y(y) {} Coord operator + (const Coord& droite) const { return Coord(x + droite.x, y + droite.y); } }; struct AB { int k; vector arbre; AB(int _k = 20, lli def = 0) { k = _k; FOR(i, 1 << k) arbre.push_back(i < (1 << (k-1)) ? 0LL : def); FORD(i, ((1 << (k-1)) - 1), 1) arbre[i] = arbre[i << 1] + arbre[(i << 1) ^ 1]; } void set(int i, lli x) { int feuille = i + (1 << (k-1)); arbre[feuille] = x; iset(feuille >> 1); } void iset(int noeud) { if(noeud) { arbre[noeud] = arbre[noeud << 1] + arbre[(noeud << 1) ^ 1]; iset(noeud >> 1); } } lli sum(int deb, int fin, int noeud = 1, int p = 0, int q = -1) { if(q < p) q = 1 << (k-1); if(deb <= p && q <= fin) return arbre[noeud]; if(deb >= q || fin <= p) return 0LL; int mil = (p + q) / 2; return sum(deb, fin, noeud << 1, p, mil) + sum(deb, fin, (noeud << 1) ^ 1, mil, q); } }; const lli MOD = 1E9+7; int m[2042]; lli dyn[2042][2042]; lli dp[2042][2042]; lli combi(lli k, lli n) { if(k < 0 || k > n) return 0; if(k == 0 || k == n) return 1; if(dp[k][n] == 0) dp[k][n] = (combi(k-1, n-1) + combi(k, n-1)) % MOD; return dp[k][n]; } bool sorted(int a, int b) { FORU(i, a, b-2) if(m[i] >= m[i+1]) return false; return true; } int main() { int n; RD(&n); FOR(i, n) RD(m+i); dyn[0][0] = 1; //FORU(j, 0, 0) // PR(dyn[0][0]); FORU(i, 1, n) { //PR(false, dyn[i][0]); FORU(j, 1, i) { lli cumul = 1; if(sorted(n-i, n-i+j)) //PR(false, '('); FOR(k, j+1) { dyn[i][j] = (dyn[i][j] + cumul * dyn[i-j][k]) % MOD; cumul = (cumul * (j-k)) % MOD; //PR(false, k, i, j, ','); } //PR(j == i, ')', dyn[i][j]); } } lli sum = 0; FOR(i, n+1) sum = (sum + dyn[n][i]) % MOD; PR(sum); return 0; }