题解 P3205 【[HNOI2010]CHORUS 合唱队】
设
②前一个排进去的人是
根据加法原理,求和,即
f[i][i+len]=
(f[i+1][i+len]*(a[i]<a[i+1])+g[i+1][i+len]*(a[i]<a[i+len]))%mod;
④前一个排进去的人是
根据加法原理,求和,即:
g[i][i+len]=
(f[i][i+len-1]*(a[i+len]>a[i])+g[i][i+len-1]*(a[i+len]>a[i+len-1]))%mod;
代码: (76ms / 9.62MB)
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1005, mod = 19650827;
int n, a[MAXN];
int f[MAXN][MAXN], g[MAXN][MAXN];
int sovle()
{
for(int i=0;i<n;i++) //初始值,只有一个人的区间只有1种情况
f[i][i]=1;
for(int len=1;len<n;len++) //最基础的区间dp
for(int i=0;i+len<n;i++)
{
f[i][i+len]=( f[i+1][i+len]*(a[i]<a[i+1]) +
g[i+1][i+len]*(a[i]<a[i+len]) )%mod; //这部分上面已经说得很清楚了
g[i][i+len]=( f[i][i+len-1]*(a[i+len]>a[i]) +
g[i][i+len-1]*(a[i+len]>a[i+len-1]) )%mod;
}
return (f[0][n-1]+g[0][n-1])%mod;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=0;i<n;i++) //读入
cin>>a[i];
cout<<sovle()<<endl;
return 0;
}