#include #include #include #include #include using namespace std; int n; const long long P = 1000000007; // our prime number long long Fact[1300]; // array of factorials mod P long long C[1300][1300]; //choose array, filled used fillC (pascals method) long long mem[1300][1300]; // our memoization table for DP bool good[1300][1300]; // good[i][j] says that elements x_i....x_j in our original array are sorted //fills C using pascals triangle long long fillC(int row, int col) { if (col == 0 || col == row) { C[row][col] = 1; } else if(C[row][col]==0) { C[row][col]= (fillC(row - 1, col - 1) + fillC(row - 1, col))%P; } return C[row][col]; } //DP function int tbcnt = 0; long long f(int i, int k) { if (i +k > n) mem[i][k]= 0; //cannot create any more arrays else if (good[i][i + k - 1] == 0) mem[i][k] = 0; //cannot divide, not sorted else if ( (i+k) == n) mem[i][k] = 1; //take all the remaning elements in one way if (mem[i][k] == -1) { long long res = 0; for (int j = 1;j <= k;j++) { if (i + j > n) break; res = (res + (((Fact[j] * C[k][j]) % P)*(f(i + k, j)))%P) % P; } mem[i][k] = res; } return mem[i][k]; } int main() { cin >> n; vector m(n); for (int m_i = 0; m_i < n; m_i++) { cin >> m[m_i]; //m[m_i] = m_i; } //initialize arrays mem, good and C for (int i = 0;i <= n;i++) for (int j = 0;j <= n;j++) { mem[i][j] = -1; good[i][j] = 0; C[i][j] = 0; } //make sure you to fill all C table for (int i = 0;i <= n;i++) for (int j = 0;j <= i;j++) fillC(i, j); //fill Fact table Fact[0] = 1; for (int i = 1;i <= n;i++) Fact[i] = (i*Fact[i - 1])%P; //fill good table for (int i = 0;i < n;i++) { good[i][i] = 1; for (int j = i + 1;j < n;j++) { if (m[j] >= m[j - 1]) good[i][j] = 1; else break; } } //calculate our answers long long res = 0; for (int k = 1;k <= n;k++) { res = (res + f(0, k)) % P; } cout << res << endl;; return 0; }