BZOJ 1996 [Hnoi2010]chorus 合唱隊
阿新 • • 發佈:2018-12-13
題目連結
題解
區間dp,記f[i][j]
表示區間,最後一個取的方案數,g[i][j]
表示區間最後一個取的方案數,狀態轉移很顯然。
程式碼
#include <cstdio>
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while ((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int maxn=1000;
const int mod=19650827;
int n,h[maxn+10],f[maxn+10][maxn+10],g[maxn+10][maxn+10];
int main()
{
n=read();
for(int i=1; i<=n; ++i)
{
h[i]=read();
}
for(int i=1; i<= n; ++i)
{
f[i][i]=1;
}
for(int len=2; len<=n; ++len)
{
for(int i=1; i+len-1<=n; ++i)
{
int j=i+len-1;
f[i][j]=(h[i]<h[i+1])*f[i+1][j]+(h[i]<h[j])*g[i+1][j];
if(f[i][j]>=mod)
{
f[i][j]-=mod;
}
g[i][j]=(h[j]>h[j-1])*g[i][j-1]+(h[j]>h[i])*f[i][j-1];
if(g[i][j]>=mod)
{
g[i][j]-=mod;
}
}
}
int ans=f[1][n]+g[1][n];
if(ans>=mod)
{
ans-=mod;
}
printf("%d\n",ans);
return 0;
}