您的位置:首页 > 其它

bzoj 1996: [Hnoi2010]chorus 合唱队 dp

2017-05-04 11:23 288 查看

题意



n<=1000,身高两两不同

分析

傻逼题。。。

f[i,j,0/1]表示排成[i,j]的队形,最后一个人排在队形的最左边/最右边的方案数。

瞎转移即可。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

const int N=1005;
const int MOD=19650827;

int a
,b
,f

[2],n;

int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
sort(b+1,b+n+1);
for (int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+n+1,a[i])-b;
for (int i=1;i<n;i++)
if (a[i]<a[i+1]) f[i][i+1][0]=f[i][i+1][1]=1;
for (int l=2;l<n;l++)
for (int i=1;i<=n-l;i++)
{
int j=i+l;
if (a[i+1]>a[i]) f[i][j][0]=(f[i][j][0]+f[i+1][j][0])%MOD;
if (a[j]>a[i]) f[i][j][0]=(f[i][j][0]+f[i+1][j][1])%MOD;
if (a[j-1]<a[j]) f[i][j][1]=(f[i][j][1]+f[i][j-1][1])%MOD;
if (a[i]<a[j]) f[i][j][1]=(f[i][j][1]+f[i][j-1][0])%MOD;
}
printf("%d",(f[1]
[0]+f[1]
[1])%MOD);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: