zoukankan      html  css  js  c++  java
  • P3205 【HNOI2010】合唱队

    # $Description$

    题面

    (n)个同学按顺序排成一队,他们都有一个身高(H_i),这个顺序称为初始队形

    现在按照以下法则重新站队:

    对于第一个同学,直接站到新队伍中,队友后面每个同学,假如在初始队伍中他比前面的同学高则站到新队伍最右边,否则站到新队伍最左边(数据保证每个同学身高不同)。所有同学以这个方法站队,形成的新队列称为最终队列。

    现在给你最终队列每个人的高度,问有多少种初始队列可以通过以上法则变成最终队列,答案对(19650827)取模。

    (Solution)

    考虑到站队的这个过程,每次让一个同学进入新队列只能到队伍的最左边或者队伍的最右边(假如初始队列为空,为避免重复考虑记为最左边),且区间长度(+1),整个过程是最终队列中的一个小区间向两边扩展。显然这道题可以使用区间(DP)解决,状态设计类似于“关路灯”这道题(仅仅是状态设计,转移过程没什么关系)。

    我们设(dp[i][j])表示初始队列从左往右站队已经完成了最终队列的(i-j)部分,发现这根本没法转移,再设计一维表示从左边插入还是从右边插入,才能利用题目条件中的法则进行转移。用(dp[i][j][0])表示最终队列已经完成了(i-j)且最新一个人从左边插入,(dp[i][j][1])表示最新一个人从右边插入。转移只有四种情况:

    (1.)当前人从左边插入和上一个人从左边插入(要求(H[i]<H[i+1]),因为我们确定(i+1)是上个人的位置,(H[i+1])就是上个人身高)

    (2.)当前人在左边插入,上一个人从右边插入(要求(H[i]<H[j])

    (3.)当前人在右,上个人在左(要求(H[j]>H[i]))

    (4.)当前人在右,上个人在右(要求(H[j]>H[j-1])

    初始化(dp[i][i][0]=1,dp[i][i][1]=0),默认每个人从左进队(反过来也行),否则答案会重复计算。

    (Code)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #define mod 19650827
    #define re register
    #define maxn 2010
    using namespace std;
    inline int read()
    {
    	int x=0,f=1; char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    int n,a[maxn],dp[maxn][maxn][2];
    int main()
    {
    	n=read();
    	for(re int i=1;i<=n;++i) a[i]=read(),dp[i][i][0]=1;
    	for(re int len=2;len<=n;++len)
    		for(re int i=1;i<=n;++i)
    		{
    			int j=i+len-1;
    			if(a[i]<a[i+1]) dp[i][j][0]+=dp[i+1][j][0];
    			if(a[i]<a[j]) dp[i][j][0]+=dp[i+1][j][1];
    			if(a[j]>a[j-1]) dp[i][j][1]+=dp[i][j-1][1];
    			if(a[j]>a[i]) dp[i][j][1]+=dp[i][j-1][0];
    			dp[i][j][1]%=mod;
    			dp[i][j][0]%=mod;
    		}
    	printf("%d",(dp[1][n][1]+dp[1][n][0])%mod);
    	return 0;
    }
    
  • 相关阅读:
    程序员必看书籍(转载)
    JBPM的ORACLE脚本
    XFire构建web service客户端的五种方式
    为什么中国出不了facebook和Twitter?
    用dwr封装表单项提交表单
    Java 程序员容易犯的10个SQL错误
    SQL语句优化方法30例
    sqlserver sql语句查看分区记录数、查看记录所在分区
    SQL Case when 的使用方法
    sqlserver sql语句附加 分离数据库
  • 原文地址:https://www.cnblogs.com/Liuz8848/p/11719556.html
Copyright © 2011-2022 走看看