[HNOI2010] 合唱队题解

题目描述

为了在即将到来的晚会上有更好的演出效果,作为 AAA 合唱队负责人的小 A 需要将合唱队的人根据他们的身高排出一个队形。假定合唱队一共 n 个人,第 i 个人的身高为 hi​ 米(1000≤hi​≤2000),并已知任何两个人的身高都不同。假定最终排出的队形是 A 个人站成一排,为了简化问题,小 A 想出了如下排队的方式:他让所有的人先按任意顺序站成一个初始队形,然后从左到右按以下原则依次将每个人插入最终排出的队形中:

  • 第一个人直接插入空的当前队形中。

  • 对从第二个人开始的每个人,如果他比前面那个人高(h 较大),那么将他插入当前队形的最右边。如果他比前面那个人矮(h 较小),那么将他插入当前队形的最左边。

当 n 个人全部插入当前队形后便获得最终排出的队形。

例如,有 6 个人站成一个初始队形,身高依次为 1850,1900,1700,1650,1800,1750,
那么小 A 会按以下步骤获得最终排出的队形:

  • 1850。

  • 1850,1900,因为 1900>1850。

  • 1700,1850,1900,因为 1700<1900。

  • 1650,1700,1850,1900,因为 1650<1700。

  • 1650,1700,1850,1900,1800,因为 1800>1650。

  • 1750,1650,1700,1850,1900,1800,因为 1750<1800。

因此,最终排出的队形是 1750,1650,1700,1850,1900,1800。

小 A 心中有一个理想队形,他想知道多少种初始队形可以获得理想的队形。

请求出答案对 19650827 取模的值。

输入格式

第一行一个整数 n。
第二行 n 个整数,表示小 A 心中的理想队形。

输出格式

输出一行一个整数,表示答案 mod19650827 的值。

输入输出样例

输入 #1复制

4
1701 1702 1703 1704

输出 #1复制

8

说明/提示

对于 30% 的数据,n≤100。
对于 100% 的数据,n≤1000,1000≤hi​≤2000。

思路

区间DP。

代码见下

#include<bits/stdc++.h>
using namespace std;
long long n,a[1005],f[1005][1005][2],mod=19650827;
int main(){
	cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        f[i][i][0]=1;
    }
    for(int i=2;i<=n;i++){
        for(int l=1;l+i-1<=n;l++){
            long long r=l+i-1;
            if(a[r-1]<a[r]){
                f[l][r][1]+=f[l][r-1][1];
            }
            if(a[l]<a[r]){
                f[l][r][1]+=f[l][r-1][0];
            }
            if(a[r]>a[l]){
                f[l][r][0]+=f[l+1][r][1];
            }      
            if(a[l+1]>a[l]){
                f[l][r][0]+=f[l+1][r][0];
            }      
            f[l][r][1]%=mod;
            f[l][r][0]%=mod;
        }
    }
    cout<<(f[1][n][1]+f[1][n][0])%mod<<endl;
	return 0;
}

posted @ 2025-10-14 21:26  bz02_2023f2  阅读(7)  评论(0)    收藏  举报  来源