Description

  

​   你有一个双端队列和 \(N\) 个数字,先按 \(1\) 到 \(N\) 的顺序每次从任意一端插入当前数字,再进行 \(N\) 次操作每次可以从两端弹出,求有多少种弹出序列满足第 \(K\) 位为 \(1\)

  

  ​ \(N \le 2000\)

  

    

  

Solution

  

​   考虑双端队列的样子,插入完成后,元素大小形象来看一定是一个"V"的形状,并且最低端是1。

  

​   再考虑符合要求的、合法的弹出序列的性质:

  

​   (1)首先第\(K\)个必须是1。

  

​   (2)前\(K-1\)个数,一定是两个或一个单调减的队列混合而成的。

  

​   (3)后\(N-K\)个数,其最大值应小于某一个(2)提到的单调队列的最小值。

  

​   一旦前\(K-1\)个数固定,最后剩下的就是一个单调的队列,取出方式有\(2^{N-K-1}\)种。

  

​   所以接下来要算出合法序列的前\(K-1\)个数有多少种情况。

  

​   设\(f_{i,j}\)表示已经确定了前\(1...i\)个数,且确定的数中最小值为\(j\),有多少种方案。

  

​   考虑从\(f_{i,j}\)转移到\(f_{i+1}\)。\(f_{i,j}\)代表着若干种符合\(j\)这个特征的长度为\(i\)的数列,不论这些数列的两个(或者一个)单调队列是怎么构成的,我们只需要看看它们能够在第\(i+1\)位填上什么数合法转移就好。

  

​   首先,下一位填\(1...j-1\)都是可行的。由于当前序列是合法序列,也就是说满足(3)。可以这样拆分出两个队列,使得一个队列的最小值是\(j\),而另一个队列专门用来满足(3)。那么将新的数接在前面那个队列后面,仍然是合法序列。所以有\(f_{i,j}\rightarrow f_{i+1,k}\;\;\;k<j\)

  

​   其次,如果要填大于\(j\)的数呢?只能填没出现过的、最大的那个数。例如\(n=7\),当前序列是7 6 3 2,只能填入5。如果填的是其他数如4,你会发现,4一定要是某一个队列的结尾,由于它不是未出现的数的最大的数,这意味着后\(N-K\)个数的数列有比它更大的,那么这个队列不满足(3)。考虑另一个队列能否满足,事实上是不可能的,因为最小值一定要是另一个队列的结尾(不然就不止2个队列了),它也不满足(3)。

  

​   所以有\(f_{i,j}\rightarrow f_{i+1,j}\)。这个转移有点神秘,它没有体现出任何\(j\)的变化,但它的确能表示,因为这一步转移相当于对每一个确切方案填了唯一确定的一个数,所以可以直接转移去对应特征的状态,也就是最小值仍然是\(j\)。

  

​   注意边界,那些\(j>n-i+1\)的\(f_{i,j}\)是不合法的,那些\(j=n-i+1\)的状态不可以用于第二类转移,因为没有空余的数可以填。

    

​   第一个转移用后缀和优化,复杂度是\(\mathcal O(n^2)\)。

  

​  

  

Code

  

#include <cstdio>
using namespace std;
const int N=2005,MOD=1e9+7;
int n,m;
int f[N];
void readData(){
scanf("%d%d",&n,&m);
}
void dp(){
f[n+1]=1;
int sum,last;
for(int i=1;i<m;i++){
sum=f[n-i+2];
for(int j=n-i+1;j>=2;j--){
(sum+=f[j])%=MOD;
if(j<=n-i+1)
f[j]=sum;
}
}
int ans=0;
for(int j=2;j<=n-(m-1)+1;j++) (ans+=f[j])%=MOD;
if(m==1) ans=1;
for(int i=1;i<=n-m-1;i++) (ans<<=1)%=MOD;
printf("%d\n",ans);
}
int main(){
readData();
dp();
return 0;
}

【ARC068F】Solitaire的更多相关文章

  1. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  2. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  3. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  4. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  5. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

  6. Python高手之路【三】python基础之函数

    基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...

  7. Python高手之路【一】初识python

    Python简介 1:Python的创始人 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种解释型.面向对象.动态数据类型的高级程序设计语言,由荷兰人Guido ...

  8. 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】

    说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...

  9. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

随机推荐

  1. SpringCloud使用Feign出现java.lang.ClassNotFoundException: org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory异常

    废话不多说!!! 在SpringCloud项目中配置了Feign来调用restful接口,项目启动的时候报错,报错信息如下: 找不到org.springframework.cloud.client.l ...

  2. .net中 多线程 笔记(基础)

    1. 在进程中可以有多个线程同时执行代码.进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把 ...

  3. 随手记录-linux-Linux目录结构

    转:别人的 装完Linux,首先需要弄清Linux 标准目录结构 / root —?启动Linux时使用的一些核心文件.如操作系统内核.引导程序Grub等. home —?存储普通用户的个人文件 ft ...

  4. JSBridge的原理

    前言 参考来源 前人栽树,后台乘凉,本文参考了以下来源 github-WebViewJavascriptBridge JSBridge-Web与Native交互之iOS篇 Ios Android Hy ...

  5. Dao DaoImp

    DAO层:DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件中定义此接口的实现类,然后就可在模块中调用此接口 ...

  6. 课堂讨论—Alpha版总结会议

    我们在课堂上针对第一阶段冲刺过程中存在的问题,展开了激烈的讨论,并投票选出需要改进的最主要三个问题. 有图有真相:

  7. 用CSS3的animation轻松实现背景动画:漂浮的云

    背景动画如果用的恰当,会给网页带来意想不到的效果.在过去,我们只能用flash或Javascript来实现.幸运的是,CSS3的流行使得我们完全可以使用它来实现这种效果,不再依赖其它编程技术.一段简单 ...

  8. T4模板_T4基本结构

    T4文本模板由 指令块.文本块.控制块 组成. 一. 指令块(MSDN文本模板指令) 指令块以@开头,基本的指令块包括<#@ template #> .<#@ parameter# ...

  9. 蜗牛慢慢爬 LeetCode 15. 3Sum [Difficulty: Medium]

    题目 Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all ...

  10. label上的事件操作执行两次

    label上的事件执行两次 标签(空格分隔): 事件执行两次 今天在做公司项目的过程中,需要在表单元素单选框上绑定事件,执行相应的操作,结果发现事件执行了两次 具体代码: <div class= ...