luogu P3205 [HNOI2010]合唱队 区间dp
#include <bits/stdc++.h> using namespace std; const int N=2020; int f[N][N][2],a[N]; int main() { int n; cin>>n; for(int i=1; i<=n; i++) cin>>a[i]; for(int i=1; i<=n; i++)//默认从左边进来 f[i][i][0]=1; //f[i,j,0] 0 i从左端进来 //f[i,j,0] 1 j从右边进来 //从左边进来肯定前1个人比他高,前1个人有2种情况,要么在i+1号位置,要么在j号位置。 //从右边进来肯定前1个人比他矮,前1个人有2种情况,要么在j-1号位置,要么在i号位置。 for(int len=1; len<=n; len++) for(int i=1,j=i+len; j<=n; i++,j++) { //对于区间i,j //i从左边进来,两种情况 //小于i+1,i+1是区间i+1,j的左端点,从左边进来的 //小于j, j 是区间i+1,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]; //j从右边进来,两种情况 //大于i ,i 是区间i,j-1的左端点 //大于j-1,j-1是区间i,j-1的右端点 if(a[i]<a[j]) 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]%=19650827; f[i][j][1]%=19650827; } cout<<(f[1][n][0]+f[1][n][1])%19650827; return 0; }