题目描述

为了在即将到来的晚会上有更好的演出效果,作为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. Spring Boot 初学避免犯不必要的错误

    创建项目时的目录问题: 新包体(例如controller)必须和启动文件 DemoApplication.java 在同一级目录下,如下 spring boot 初步使用创建新的项目:https:// ...

  2. MApp_ZUI_CTL_MarqueeTextWinProc字串滚动

    /////////////////////////////////////////////////////////////////////////////// /// global MApp_ZUI_ ...

  3. QT 头文件之间相互包含会报错:类名不存在

    "希望是一个美好的东西! 希望, 这能自己给自己,否则只有无尽的痛苦和迷茫!"---Frank 假设你写了两个类A和B,如果在A.h中有 #include<B.h>;  ...

  4. [CF9D]How Many Trees?_动态规划_树形dp_ntt

    How many trees? 题目链接:https://www.codeforces.com/contest/9/problem/D 数据范围:略. 题解: 水题. $f_{i,j}$表示$i$个节 ...

  5. [转帖]时间序列数据库 (TSDB)

    时间序列数据库 (TSDB) https://www.jianshu.com/p/31afb8492eff 0.3392019.01.28 10:51:33字数 5598阅读 4030 背景 2017 ...

  6. 二进制知识(java中的位操作)

    文章目录 前言 机器数 真值 原码 反码 补码 计算机中保存的都是补码 位操作 强制转换,精度丢失 前言 讲二进制的东西,必须要说明是多少位机器,八位机上的 1000 1000 和 十六位机上的 10 ...

  7. SQLLite日期时间函数

    SQLLite包含了如下时间/日期函数:datetime().......................产生日期和时间date()...........................产生日期tim ...

  8. Linux下实现web服务器

    说明:暂时只是实现了静态网页的响应 #include <stdio.h> #include <sys/types.h> /* See NOTES */ #include < ...

  9. ActiveMQ 消息队列服务

      1 ActiveMQ简介 1.1 ActiveMQ是什么 ActiveMQ是一个消息队列应用服务器(推送服务器).支持JMS规范. 1.1.1 JMS概述 全称:Java Message Serv ...

  10. vue 百度云上传文件PostObject

    百度云上传文件 API(PostObject) PostObject接口  : 接口描述 此接口使用HTML表单上传文件到指定bucket,用于实现通过浏览器上传文件到bucket.在PutObjec ...