[HNOI2010]合唱队
题解:
我们设dp[i][j][0/1]表示最终序列从i到j最后放的是i/j(0/1).
很显然的转移
if(h[i]<h[i+1]) dp[i][j][0]=dp[i+1][j][0];
if(h[i]<h[j]) (dp[i][j][0]+=dp[i+1][j][1])%=mod;
if(h[j]>h[j-1]) dp[i][j][1]=dp[i][j-1][1];
if(h[j]>h[i]) (dp[i][j][1]+=dp[i][j-1][0])%=mod;
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<cmath> 5 #include<algorithm> 6 #include<cstring> 7 #include<queue> 8 #include<vector> 9 #include<stack> 10 #include<map> 11 #define RG register 12 #define MAXN 3000010 13 #define LL long long int 14 using namespace std; 15 const int INF=1e9; 16 const int mod=19650827; 17 int n; 18 int h[MAXN]; 19 LL dp[1010][1010][2]; 20 int main() 21 { 22 freopen("1.in","r" ,stdin); 23 scanf("%d",&n); 24 for(int i=1;i<=n;i++) scanf("%d",&h[i]),dp[i][i][0]=1; 25 for(int len=2;len<=n;len++) 26 for(int i=1;i+len-1<=n;i++) 27 { 28 int j=i+len-1; 29 if(h[i]<h[i+1]) dp[i][j][0]=dp[i+1][j][0]; 30 if(h[i]<h[j]) (dp[i][j][0]+=dp[i+1][j][1])%=mod; 31 if(h[j]>h[j-1]) dp[i][j][1]=dp[i][j-1][1]; 32 if(h[j]>h[i]) (dp[i][j][1]+=dp[i][j-1][0])%=mod; 33 } 34 printf("%lld\n",(dp[1][n][0]+dp[1][n][1])%mod); 35 return 0; 36 }