区间dp。。
设f[i][j][0]为从i选到j时上一次选左边的方案数,f[i][j][1]为右边的方案数,然后就那样了。。
f[i][j][0]=f[i+1][j][0]*(a[i]<a[i+1])+f[i+1][j][1]*(a[i]<a[j])
f[i][j][1]=f[i][j+1][0]+(a[j]>a[i])+f[i][j+1][1]*(a[j]>a[j-1])
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 using namespace std; 7 8 const int M=19650827; 9 10 int f[2000][2000][2],n,a[2000]; 11 12 int main(){ 13 for(int i=scanf("%d",&n)&0;i<n;i++) 14 scanf("%d",a+i+1),f[i+1][i+1][0]=1; 15 for(int len=2;len<=n;len++){ 16 for(int i=1;i<=n;i++){ 17 int j=i+len-1; 18 if(j>n)break; 19 f[i][j][0]=f[i+1][j][0]*(a[i]<a[i+1])+f[i+1][j][1]*(a[i]<a[j]); 20 f[i][j][1]=f[i][j-1][0]*(a[j]>a[i])+f[i][j-1][1]*(a[j]>a[j-1]); 21 f[i][j][0]%=M; 22 f[i][j][1]%=M; 23 } 24 } 25 printf("%d\n",(f[1][n][0]+f[1][n][1])%M); 26 }