bzoj 1996: [Hnoi2010]chorus 合唱队
区间型DP f[i][j]表示形成这段区间的方案数,同时记录一下是以i还是j结尾。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<queue> 7 #include<algorithm> 8 #include<vector> 9 #define M 1009 10 #define EPS 1e-10 11 #define MO 19650827 12 #define ll long long 13 using namespace std; 14 ll read() 15 { 16 char ch=getchar(); 17 ll x=0,f=1; 18 for(;ch<'0'||ch>'9';ch=getchar()) 19 if(ch=='-') 20 f=-1; 21 for(;ch>='0'&&ch<='9';ch=getchar()) 22 x=x*10+ch-'0'; 23 return x*f; 24 } 25 int n,f[M][M][2],a[M]; 26 void jia(int &x,int y) 27 { 28 x+=y; 29 if(x>MO) 30 x-=MO; 31 } 32 int main() 33 { 34 n=read(); 35 for(int i=1;i<=n;i++) 36 a[i]=read(); 37 for(int i=1;i<=n;i++) 38 f[i][i][0]=1; 39 for(int i=n;i;i--) 40 for(int j=i+1;j<=n;j++) 41 { 42 if(a[i+1]>a[i]) 43 jia(f[i][j][0],f[i+1][j][0]); 44 if(a[j]>a[i]) 45 jia(f[i][j][0],f[i+1][j][1]); 46 if(a[j-1]<a[j]) 47 jia(f[i][j][1],f[i][j-1][1]); 48 if(a[i]<a[j]) 49 jia(f[i][j][1],f[i][j-1][0]); 50 } 51 printf("%d\n",(f[1][n][0]+f[1][n][1])%MO); 52 return 0; 53 }