bzoj 1996: [Hnoi2010]chorus 合唱队 dp

来源:互联网 发布:大学生体育锻炼数据 编辑:程序博客网 时间:2024/06/03 04:44

题意

这里写图片描述
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[N],b[N],f[N][N][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][n][0]+f[1][n][1])%MOD);    return 0;}
0 0
原创粉丝点击