题目描述

为了在即将到来的晚会上有更好的演出效果,作为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心中有一个理想队形,他想知道多少种初始队形可以获得理想的队形

说明/提示

30%的数据:n<=100

100%的数据:n<=1000

解析

其实这道题是递推/记搜。

观察题目,容易归纳出每次取一个人加入队形时,他只可能加在队列的最左边或者最右边,满足区间dp的性质。

设\(dp[0/1][i][j]\)表示在区间\(i\sim j\)中最后放的人在最左/右时的方案数。

根据加法原理,容易写出状态转移方程:

\[dp[i][j][0] = dp[i + 1][j][0] · [h_i < h_{i+1}] + dp[i + 1][j][1] · [h_i < h_j
]\\
dp[i][j][1] = dp[i][j − 1][0] · [h_j > h_i
] + dp[i][j - 1][1] · [h_j > h_{j−1}]
\]

自认为这题比较神奇的一点(我WA了好几次),是初始化,鬼知道为什么只用初始化一维(\(0/1\)那一维),而且无论你初始化哪一维答案都是一样的。

参考代码

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#define mod 19650827
#define N 1010
using namespace std;
int dp[2][N][N],n,a[N];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]),dp[0][i][i]=1;
for(int len=2;len<=n;++len)
for(int l=1;l<=n-len+1;++l){
int r=l+len-1;
// 0 left 1 right
int t1=0,t2=0,t3=0,t4=0;
if(a[l]<a[l+1]) t1=1;
if(a[l]<a[r]) t2=1;
if(a[r]>a[r-1]) t3=1;
if(a[r]>a[l]) t4=1;
dp[0][l][r]=(dp[0][l+1][r]*t1%mod+dp[1][l+1][r]*t2%mod)%mod;
dp[1][l][r]=(dp[1][l][r-1]*t3%mod+dp[0][l][r-1]*t4%mod)%mod;
}
printf("%d\n",((dp[0][1][n]%mod+dp[1][1][n])%mod)%mod);
return 0;
}

P3205 [HNOI2010]合唱队[区间dp]的更多相关文章

  1. [HNOI2010]合唱队 区间DP

    ---题面--- 题解: 偶然翻到这道题,,,就写了. 观察到一个数被插在哪里只受前一个数的影响,如果明确了前一个数是哪个,那么我们就可以确定大小关系,就可以知道当前这个数插在哪里,而上一个插入的数就 ...

  2. 洛谷 P3205 [HNOI2010]合唱队 解题报告

    P3205 [HNOI2010]合唱队 题目描述 为了在即将到来的晚会上有更好的演出效果,作为AAA合唱队负责人的小A需要将合唱队的人根据他们的身高排出一个队形.假定合唱队一共N个人,第i个人的身高为 ...

  3. 洛谷——P3205 [HNOI2010]合唱队

    P3205 [HNOI2010]合唱队 题目描述 为了在即将到来的晚会上有更好的演出效果,作为AAA合唱队负责人的小A需要将合唱队的人根据他们的身高排出一个队形.假定合唱队一共N个人,第i个人的身高为 ...

  4. 【BZOJ1996】【HNOI2010】合唱队 [区间DP]

    合唱队 Time Limit: 4 Sec  Memory Limit: 64 MB[Submit][Status][Discuss] Description Input Output Sample ...

  5. BZOJ1996:[HNOI2010]CHORUS 合唱队(区间DP)

    Description Input Output Sample Input 4 1701 1702 1703 1704 Sample Output 8 HINT Solution 辣鸡guide真难用 ...

  6. [HNOI2010]CHORUS 合唱队 (区间DP)

    题目描述 对于一个包含 NN 个整数的数列 AA ,我们可以把它的所有元素加入一个双头队列 BB . 首先 A1A1 作为队列的唯一元素,然后依次加入 A2∼ANA2∼AN ,如果 Ai<Ai− ...

  7. LG3205/BZOJ1996 「HNOI2010」合唱队 区间DP

    区间DP 区间DP: 显然是一个区间向左右拓展形成的下一个区间,具有包含关系,所以可以使用区间DP. 状态设计: 考虑和关路灯一样设计状态 因为不知道当前这个区间是从哪个区间拓展而来,即不知道这个区间 ...

  8. [洛谷P3205] HNOI2010 合唱队

    问题描述 为了在即将到来的晚会上有更好的演出效果,作为AAA合唱队负责人的小A需要将合唱队的人根据他们的身高排出一个队形.假定合唱队一共N个人,第i个人的身高为Hi米(1000<=Hi<= ...

  9. 洛谷 P3205 [HNOI2010]合唱队

    题目链接 题解 区间dp \(f[i][j]\)表示i~j区间最后一次插入的是\(a[i]\) \(g[i][j]\)表示i~j区间最后一次插入的是\(a[j]\) 然后就是普通区间dp转移 Code ...

随机推荐

  1. nginx配置访问本地静态资源

    下面说说如何在windows下使用nginx作为静态资源服务器, 1.修改config目录下,这个配置文件,基本上所有的配置都在这里面做, 2.主要的配置参数如下,一些无关的参数我直接去掉了,注意,里 ...

  2. java properties文件转义字符和中文乱码解决

    properties文件的分隔符是   =或者 : 第一次出现的就是分割符,第二次出现的也不需要转义,也即是(忽略掉[],只是着重描述字符) [\=]     [\:]   或者  [=]  [:] ...

  3. 谈谈redis的热key问题如何解决

    引言 讲了几天的数据库系列的文章,大家一定看烦了,其实还没讲完...(以下省略一万字).今天我们换换口味,来写redis方面的内容,谈谈热key问题如何解决.其实热key问题说来也很简单,就是瞬间有几 ...

  4. [PDF] - 获取 RadioButtonList 控件值的方法

    背景 目标是通过 iTextSharp 读取 PDF 模板,填充内容后以生成新 PDF 文件.利用 福昕PDF编辑器个人版 可以获取到 RadioButtonList 的组名,但是获取不到每一个 Ra ...

  5. (一)Shiro,久闻其名,而今初相识

    文章目录 shiro简介 功能介绍 从外部看 Shiro 架构 从内部看 Shiro 架构 多说一句,在学习shiro之前,我觉得应该先用 filter ,自己动手写过粗粒度的权限系统,而不要一上来就 ...

  6. C++语言类之间的关系

    在c++中通过类定义对象,而类与类之间也有着复杂的关系,所以题外话,我能理解到c++的编写者可能就想通过计算机语言去模拟世界万物之间的关系,这篇帖子主要从横向和纵向去讨论类之间关系 而在一个类中想要使 ...

  7. 静态成员函数和(CPP与C结构体的区别)

    #include <iostream> using namespace std.; //这种写法只是CPP中的struct的用法,但是在C中还是不支持的. //C中的结构体不支持写方法的. ...

  8. HttpClient 远程接口调用方式

    远程接口调用方式HttpClient 问题:现在我们已经开发好了接口了,那该如何调用这个接口呢? 答:使用Httpclient客户端.   Httpclient简介 什么是httpclient Htt ...

  9. Authentication源码解析

    1.获取当前的 Subject. 调用 SecurityUtils.getSubject(); 从当前线程的threadLocals属性中获取Subject对象 SecurityUtils publi ...

  10. Inline Hook 钩子编写技巧

    Hook 技术通常被称为钩子技术,Hook技术是Windows系统用于替代中断机制的具体实现,钩子的含义就是在程序还没有调用系统函数之前,钩子捕获调用消息并获得控制权,在执行系统调用之前执行自身程序, ...