題目描述
輸入格式
輸出格式
樣例輸入
4
1701 1702 1703 1704
樣例輸出
8
提示
題解
發現題目要求的是方案數,那麼我們想到了區間DP。
由於題目給定的加入元素的方式,我們可以清楚的知道新元素要麼加在隊頭要麼加在隊尾,所以說在某種程度上這個序列是連續的(或者說有特殊的性質),並且對於新加入的元素的位置的影響只跟上一次的加入元素有關。
根據這個特殊性質我們想到了區間DP,令
那麼顯然,初值即爲
這樣跑一遍區間DP最後答案顯然就是
轉移方程:
代碼
#include <cstdio>
#include <cstring>
#include <algorithm>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
const int size = 1000+10;
const int mod = 19650827;
int a[size],f[size][size][2];
int n;
inline int read(int &in) {
in=0;int f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
for(;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0';
return in*f;
}
int main() {
read(n);
for(int i=1;i<=n;i++) read(a[i]);
for(int i=1;i<=n;i++) f[i][i][1]=1;
for(int i=n;i>=1;i--)
for(int j=i+1;j<=n;j++) {
if (a[i]<a[i+1])f[i][j][0]+=f[i+1][j][0];
if (a[i]<a[j])f[i][j][0]+=f[i+1][j][1];
if (a[j]>a[i])f[i][j][1]+=f[i][j-1][0];
if (a[j]>a[j-1])f[i][j][1]+=f[i][j-1][1];
f[i][j][0]%=mod; f[i][j][1]%=mod;
}
printf("%d\n",(f[1][n][0]+f[1][n][1])%mod);
return 0;
}