版权声明:我这么弱的蒟蒻,虽然博文不是很好,但也请标明转发地址喵! https://blog.csdn.net/ACerAndAKer/article/details/82217111
区间dp
我们考虑两个数组f[i][j]和g[i][j]
f[i][j]表示构成理想区间i~j,最后一个插进去的是i的方案,g[i][j]表示构成理想区间i~j,最后一个插进去的是j的方案
对于f[i][j]
1.前一个插进去的是i+1,那么i能插到i+1左边的条件是a[i]<a[i+1]--->f[i+1][j]
2.前一个插进去的是j,那么i能插到i+1左边的条件是a[i]<a[j]--->g[i+1][j]
所以f[i][j]=f[i+1][j]*(a[i[<a[i+1])+g[i+1][j]*(a[i]<a[j])
对于g[i][j]
1.前一个插进去的是i,那么j能插到j-1的右边的条件是a[j]>a[i]--->f[i][j-1]
2.前一个插进去的是j-1,那么j能插到j-1的右边的条件是a[j]>a[j-1]--->g[i][j-1]
所以g[i][j]=f[i][j-1]*(a[i]<a[j])+g[i][j-1]*(a[j]>a[j-1])
然后初始的时候f[i][i]=1,然后正常区间dp就好了
代码
//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=1050;
const int mod=19650827;
int n,f[M][M],a[M],g[M][M];
inline int read()
{
int x=0;char ch=getchar();
while (ch>'9'||ch<'0') ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
signed main()
{
n=read();
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=n;i++) f[i][i]=1;
for (int i=1;i<n;i++)
for (int k=1;k+i<=n;k++)
f[k][i+k]=(f[k+1][i+k]*(a[k]<a[k+1])+g[k+1][i+k]*(a[k]<a[k+i]))%mod,
g[k][i+k]=(f[k][i+k-1]*(a[k]<a[i+k])+g[k][i+k-1]*(a[i+k]>a[i+k-1]))%mod;
cout<<(f[1][n]+g[1][n])%mod;
return 0;
}