#include #define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i=i+1) #define FORD(i,b,a) for (int i=(b),_a=(a);i>=_a;i=i-1) #define REP(i,n) for (int i=0,_n=(n);i<_n;i=i+1) #define FORE(i,v) for (__typeof((v).begin()) i=(v).begin();i!=(v).end();i++) #define ALL(v) (v).begin(),(v).end() #define fi first #define se second #define MASK(i) (1LL<<(i)) #define BIT(x,i) (((x)>>(i))&1) #define div ___div #define next ___next #define prev ___prev #define left ___left #define right ___right #define __builtin_popcount __builtin_popcountll using namespace std; template void minimize(X &x,const Y &y) { if (x>y) x=y; } template void maximize(X &x,const Y &y) { if (x T Abs(const T &x) { return (x<0?-x:x); } /* Author: Van Hanh Pham */ /** END OF TEMPLATE - ACTUAL SOLUTION COMES HERE **/ #define MAX 1212 const int MOD = (int)1e9 + 7; int value[MAX], n; int breakPoint[MAX]; int frac[MAX], finv[MAX]; int f[MAX][MAX]; int inverse(int x) { int res = 1; int mul = x; int k = MOD - 2; while (k > 0) { if (k & 1) res = 1LL * res * mul % MOD; mul = 1LL * mul * mul % MOD; k >>= 1; } assert(1LL * res * x % MOD == 1); return res; } void init(void) { scanf("%d", &n); FOR(i, 1, n) scanf("%d", &value[i]); frac[0] = finv[0] = 1; FOR(i, 1, n) { frac[i] = 1LL * frac[i - 1] * i % MOD; finv[i] = inverse(frac[i]); } vector points; FOR(i, 2, n) if (value[i] <= value[i - 1]) points.push_back(i); points.push_back(n + 1); FOR(i, 1, n) { int id = upper_bound(ALL(points), i) - points.begin(); breakPoint[i] = points[id]; } } void add(int &x, const int &y) { x += y; if (x >= MOD) x -= MOD; } void optimize(void) { FOR(i, 1, breakPoint[1] - 1) f[i][i] = 1; FOR(used, 1, n) FOR(prev, 1, used) if (f[used][prev] > 0) FOR(next, 1, min(prev, n - used)) { if (used + next >= breakPoint[used + 1]) break; add(f[used + next][next], 1LL * f[used][prev] * frac[prev] % MOD * finv[prev - next] % MOD); } int res = 0; FOR(i, 1, n) add(res, f[n][i]); printf("%d\n", res); } int main(void) { init(); optimize(); return 0; } /*** LOOK AT MY CODE. MY CODE IS AMAZING :D ***/