对于最终的序列$a_{i}$,条件如下:

1.$a_{i}$是一个排列,且$a_{k}=1$

2.不存在三元组$1\le x<y<z<k$,使得$a_{x}<a_{y}<a_{z}$

3.$\forall k<x$,$a_{x}>\max_{x<y\le n}a_{y}$或$a_{x}<\max_{x<y\le n}a_{y}$

4.$\max(\min_{1\le x<y<k,a_{x}<a_{y}}a_{x},a_{k-1})>\max_{k<x\le n}a_{x}$(左式$y$的意义是要求$x$满足存在$y$,且若不存在$x$其值定义为$n+1$)

下面稍微解释一下(仅说明必要性)——

第一个条件显然,就不说明了

假设队列中的数从队首开始,依次为$b_{1},b_{2},...,b_{n}$,其中$b_{t}=1$,不难得到有$\forall 1\le i<t,b_{i}>b_{i+1}$以及$\forall i<t\le n,b_{i-1}<b_{i}$

在取出1之前,当在队首/队尾取出一个数字$x$后,考虑此时队尾/队首的数字$y$,若$x<y$则说明在$x$之前不存在比$x$小的数字,反之则说明$x$之后不存在比$x$大的数字,这等价于第2个条件

在取出1之后,队列中也就剩下一个单调的数列,此时从队首取出的数必然比之后所有数都小,从队尾取出的数必然比之后所有数都大,这等价于第3个条件

不妨假设1是从队首取出,那么考虑1取出前从队首和队尾取出的最后一个数字$x=b_{t-1}$和$y$,根据单调性$y$需要大于剩下单调队列中的最大值,也即$\max_{k<x\le n}a_{x}$

当$x>y$,不妨将队首和队尾这两段交换,因此可以看作$\max(x,y)>\max_{k<x\le n}a_{x}$

关于$\max(x,y)$的值,首先$x$和$y$中必然有一个数是$a_{k-1}$,不妨假设为$x$,之后从$a_{k-1}$向前,找到第一个不单调递增的位置,将这个作为$y$一定最大,根据条件2,其之前所有数都比其小,因此$y=\min_{1\le x<y<k,a_{x}<a_{y}}a_{x}$,而$\max(x,y)>\max_{k<x\le n}a_{x}$即等价于第4个条件

当我们确定$a_{i}$的前$k$个数后,根据条件1,令未出现的数构成集合$S$,那么剩下的数即$S$中所有数的一个排列,因此有$\max_{k<x\le n}a_{x}=\max_{x\in S}x$,由此即可判定条件4,另外条件1和2也可以容易地判定

此时,对于条件3,除去$a_{n}$以外,每一个数不可能同时满足这两个条件,当确定每一个数满足的条件后,不难发现我们可以恰好构造出一组解(若满足$a_{x}>\max_{x<y\le n}a_{x}$,则$a_{x}$为$S$的最大值,之后删除$S$中的最大值,另一种类似),因此解数即为$2^{n-k-1}$

对于前$k-1$个数($a_{k}=1$即不需要考虑),考虑dp计算,用$f_{i,j,k}$表示确定前$i$个数、$\min_{1\le x\le i}a_{x}=j$且$\max(\min_{1\le x<y\le i,a_{x}<a_{y}}a_{x},a_{i})=k$的方案数

由于排列的性质,我们要考虑已经出现过的数,根据$j$最小显然先比$j$小的数必然都没有出现,其次比$k$大的数字必然都出现过,原因如下:

若$k=n+1$显然成立,因此$k\ne n+1$,即存在这样的$(x,y)$满足$a_{x}<a_{y}$,根据条件2之后就不能出现比$k$大的数(直至1出现为止),同时$k$单调不增,而最终这个未出现的数在$S$中,有$\max_{x\in S}x>k$,不满足条件4

下面考虑转移,分两类讨论:

1.当我们新加入一个比$j$小的数字,显然$j$转换为新的数,$k$不变

2.当我们新加入一个比$k$小且比$j$大的数字$x$,由于$j$和$x$满足,因此$k=\max(j,x)=x$,而比$k$大的数都需要出现,因此$x$必然是比$k$小且最大的未出现的数

当然,$x$需要比$j$大,即$j$到$k$之间的数不能全部出现,显然这等价于$n-j+1>i$

事实上,我们发现$k$这个状态是多余的,用$f_{i,j}$表示前$i$个数且$\min_{1\le x\le i}a_{x}=j$,综上即可递推计算,$f_{i,j}$转移到$f_{i+1,k}$($2\le k<j$),若$n-j+1>i$,还可以转移到$f_{i+1,j}$

将这个过程转换为$f_{i,j}=\sum_{k=j}^{n+1}f_{i-1,k}$(特别的,若$n-j+1<i$则$f_{i,j}=0$),后缀和优化即可,时间复杂度为$o(n^{2})$,可以通过

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 2005
4 #define mod 1000000007
5 int n,k,ans,f[N][N],sum[N][N];
6 int main(){
7 scanf("%d%d",&n,&k);
8 f[0][n+1]=1;
9 for(int i=2;i<=n+1;i++)sum[0][i]=1;
10 for(int i=1;i<k;i++){
11 for(int j=2;j<=n+1;j++)
12 if (n-j+1<i)f[i][j]=0;
13 else f[i][j]=sum[i-1][j];
14 sum[i][n+1]=f[i][n+1];
15 for(int j=n;j>1;j--)sum[i][j]=(sum[i][j+1]+f[i][j])%mod;
16 }
17 ans=sum[k-1][2];
18 for(int i=1;i<n-k;i++)ans=2*ans%mod;
19 printf("%d",ans);
20 }

[atARC068F]Solitaire的更多相关文章

  1. 1455.Solitaire(bfs状态混摇)

    Solitaire Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  2. Codeforces Gym 100231F Solitaire 折半搜索

    Solitaire 题目连接: http://codeforces.com/gym/100231/ Description 给你一个8*8棋盘,里面有4个棋子,每个棋子可以做一下某个操作之一: 1.走 ...

  3. ruby quiz The Solitaire Cipher

    solitaire cipher:http://en.wikipedia.org/wiki/Solitaire_(cipher) https://www.schneier.com/solitaire. ...

  4. UVA 10651 Pebble Solitaire(bfs + 哈希判重(记忆化搜索?))

    Problem A Pebble Solitaire Input: standard input Output: standard output Time Limit: 1 second Pebble ...

  5. uva 10651 - Pebble Solitaire(记忆化搜索)

    题目链接:10651 - Pebble Solitaire 题目大意:给出一个12格的棋盘,‘o'代表摆放棋子,’-‘代表没有棋子, 当满足’-oo'时, 最右边的棋子可以跳到最左边的位子,而中间的棋 ...

  6. Solitaire

    Solitaire Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  7. Hdu1401 Solitaire 2017-01-18 17:21 33人阅读 评论(0) 收藏

    Solitaire Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Sub ...

  8. UVa 10651 Pebble Solitaire(DP 记忆化搜索)

    Pebble Solitaire Pebble solitaire is an interesting game. This is a game where you are given a board ...

  9. win10 LTSC系统 安装应用商店和纸牌合集,解决从应用商店安装Solitaire Collection纸牌打开空白的问题

    家里台式机换了win10系统,想给老妈玩那个纸牌游戏(我也超喜欢的!. 发现这个系统没有自带纸牌游戏Microsoft Solitaire Collection, 过分的是,连应用商店都没有...呵呵 ...

随机推荐

  1. Windows下node-gyp查找VS安装路径简单解析

    node-gyp的作用我已经不想赘述了,这里给一个我之前文章的链接:cnblogs看这里,知乎看这里.本文主要从源码入手,介绍node-gyp查找VisualStudio的过程 为了方便我们研究nod ...

  2. CSS写一个圣诞树Chrome浏览器小插件

    一时兴起,突然想写一个Chrome浏览器插件,不知道写啥,就写了一个圣诞树小插件.项目源码>> Chrome浏览器插件 Chrome浏览器插件最主要的是:index.html.manife ...

  3. 运用shapefile.js解析Shp文件

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...

  4. k8s学习笔记(1)- 简单部署springboot应用

    前言:k8s全称kubernetes,k8s是为容器服务而生的一个可移植容器的编排管理工具,越来越多的公司正在拥抱k8s,并且当前k8s已经主导了云业务流程,关于更多的k8s知识,可自行学习 1.k8 ...

  5. Oil Deposits 新年特辑篇

    链接:E - Oil Deposits 题目: The GeoSurvComp geologic survey company is responsible for detecting undergr ...

  6. python的参数传递是值传递还是引用传递??

    函数参数传递机制,传值和引用的是什么意思? 函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题.基本的参数传递机制有两种:值传递和引用传递. 值传递(pa ...

  7. 永久修改alias

    永久修改alias home目录下ls -a显示隐藏文件 编辑./cshrc

  8. (课内)信安数基RSA-基础&&解密加速

    RSA基本实现 首先获得N比特的伪随机数:使用Random库中内容. randint(n,m) 表示生成一个在n和m之间的随机数, **表示乘幂. getPrime找素数,or 1运算是一种优化:如果 ...

  9. 【Spring】IoC容器 - 依赖来源

    前言 上一篇文章已经学习了[依赖注入]相关的知识,这里详细的介绍一下[依赖来源]. 依赖来源 我们把依赖来源分为依赖查找的来源和依赖注入的来源分别讨论. 依赖查找的来源 1. Spring BeanD ...

  10. 【数据结构 C++】排序——冒泡、插入、选择、希尔、归并、快排、堆排序

    LeetCode 912. 排序数组 给你一个整数数组 nums,请你将该数组升序排列. 示例 1: 输入:nums = [5,2,3,1] 输出:[1,2,3,5] 示例 2: 输入:nums = ...