很容易想到区间DP

然后发现这个区间只和圆序列的最后一个数有关,而原序列的最后一个数只可能是现在区间的头或者尾

令$f[i][j][0/1]$表示在区间$[i, j]$之间,原序列的最后一个数是当前区间的头/尾的总答案数

于是只要讨论$a[i], a[i + 1], a[j - 1], a[j]$之间的关系搞一搞就可以了

 

 1 /**************************************************************
 2     Problem: 1996
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:112 ms
 7     Memory:8700 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <cstring>
12   
13 using namespace std;
14 const int N = (int) 1e3 + 5;
15 const int mod = 19650827;
16   
17 int n, a[N];
18 int f[N][N][2], ans;
19   
20 int main() {
21     int i, j, len;
22     scanf("%d", &n);
23     if (n == 1) {
24         puts("1");
25         return 0;
26     }
27     for (i = 1; i <= n; ++i) scanf("%d", a + i);
28     for (i = 1; i < n; ++i)
29         f[i][i + 1][0] = f[i][i + 1][1] = bool(a[i] < a[i + 1]);
30     for (len = 3; len <= n; ++len)
31         for (i = 1; i <= n - len + 1; ++i) {
32             j = i + len - 1, f[i][j][0] = f[i][j][1] = 0;
33             if (a[j] > a[j - 1]) f[i][j][1] += f[i][j - 1][1];
34             if (a[j] > a[i]) f[i][j][1] += f[i][j - 1][0];
35             if (a[i] < a[i + 1]) f[i][j][0] += f[i + 1][j][0];
36             if (a[i] < a[j]) f[i][j][0] += f[i + 1][j][1];
37             f[i][j][0] %= mod, f[i][j][1] %= mod;
38         }
39     ans = (f[1][n][0] + f[1][n][1]) % mod;
40     printf("%d\n", ans);
41     return 0;
42 }
View Code

 

posted on 2015-05-16 23:31  Xs酱~  阅读(198)  评论(0编辑  收藏  举报