[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
",(dp[1][n][0]+dp[1][n][1])%mod);
35   return 0;
36 }
原文地址:https://www.cnblogs.com/Landlord-greatly/p/8081734.html