很容易想到区间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 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen