原题链接
这道题相对简单,注意到对于给定的最终队列,最后一个加入的人要么在队首要么在队尾,假设其长度为n,则其可能由其两个长度为n-1的子区间队列转化而来,状态转移时分4类判断可能由哪些状态转移而来,情况数量累加即可。
使用三维的状态存储数组,便于状态分类和转移。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include<iostream> #include<algorithm> #include<cstring> #define fastIO ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0); using namespace std;
const int N=1010,mod=19650827;
int dp[N][N][2]; int n,h[N];
int main(){ fastIO cin>>n; for(int i=1;i<=n;i++) cin>>h[i]; for(int i=1;i<=n;i++) dp[i][i][0]=1;
for(int l=2;l<=n;l++){ for(int i=1;i+l-1<=n;i++){ int j=i+l-1; if(h[i]<h[i+1]) dp[i][j][0]=(dp[i][j][0]+dp[i+1][j][0])%mod; if(h[i]<h[j]) dp[i][j][0]=(dp[i][j][0]+dp[i+1][j][1])%mod; if(h[j]>h[i]) dp[i][j][1]=(dp[i][j][1]+dp[i][j-1][0])%mod; if(h[j]>h[j-1]) dp[i][j][1]=(dp[i][j][1]+dp[i][j-1][1])%mod; } } cout<<(dp[1][n][1]+dp[1][n][0])%mod<<endl;
return 0; }
|