[ARC068F] Solitaire [DP]
题面
思路
单调性
首先,显然可以发现这些数在放进双端队列之后肯定是一个$V$形的排布:1在最中间,两边的数都是单调递增
那么我们拿出来的数,显然也可以划分成2个单调递减的子序列(因为我们也是从两边往中间取的)
我们令这两个单调递减的子序列的最小值分别为$p$和$q$,其中$p<q$
那么,有一个结论:任意的的还没有被选取的数$k<q$,证明就是用上面的单调递减理论。
如果有一个数比$q$还要大,那么它肯定会在$p,q$之前被拿出队列,因此不会还没有被选取。
递推
考虑我们新放进一个数$k$
如果$p<k<q$,那么显然这个$k$只能放到$q$的那个单调序列的末尾此时这个单调序列的最小值就是$k$了,但是整个已经拿出来的集合的最小值还是$p$
如果$k<p$,那么$k$可以放到两个单调序列的任意一个的末尾。这两种情况下我们分别会得到$(k,p)$和$(q,k)$这两种最小值组合,此时集合最小值一定为$k$
可以发现,这两种情况中,改变了的都是最小值,而且两种情况之间的不同之处也在于新加入的元素和最小值的大小关系
那么,我们就可以考虑一个以当前取出的数集合大小和最小值为状态的$dp$
设$dp[i][j]$表示当前取出了$i$个数,其中的最小值是$j$
那么由上面的讨论,可以得到状态转移方程:
$dp[i][j]=dp[i-1][j]+\sum_{k>j}dp[i-1][k]=\sum_{k>=j}dp[i-1][k]$
到了K以后的问题
显然,上面方程中的$i$,取值范围是$[1,K)$
第$K$个数要求是放1,那么显然这个1只能放在最小值所在的那个序列末尾
后面剩下的$n-K$个数显然就随便取了,一共有$2^{n-K-1}$种选法(最后一个不用乘2)
那么答案就是$2{n-K-1}\sum_{i=2}{n-K+2} dp[K-1][i]$
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<cmath>
#define ll long long
#define MOD 1000000007
using namespace std;
inline ll read(){
ll re=0,flag=1;char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') flag=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
ll dp[2010][2010],p[2010],sum[2010][2010];
int main(){
ll n=read(),k=read();ll i,j;
p[0]=1;
for(i=1;i<=n;i++) p[i]=p[i-1]*2%MOD;
for(i=2;i<=n;i++) dp[1][i]=1,sum[1][i]=n-i+1;
for(i=2;i<k;i++){
for(j=n-i+1;j>=2;j--){
dp[i][j]=(dp[i-1][j]+sum[i-1][j+1])%MOD;
//这里我分开写了,这样清晰一点
}
for(j=n-i+1;j>=2;j--) sum[i][j]=(sum[i][j+1]+dp[i][j])%MOD;
}
ll ans=0;
for(i=2;i<=n-k+2;i++) ans+=dp[k-1][i],ans%=MOD;
if(k==1) ans=1;
if(k==n) printf("%lld\n",ans);
else printf("%lld\n",ans*p[n-k-1]%MOD);
}
[ARC068F] Solitaire [DP]的更多相关文章
- LOJ #2731 [JOI2016春季合宿]Solitaire (DP、组合计数)
题目链接 https://loj.ac/problem/2731 题解 首先一个很自然的思路是,设\(dp[i][j]\)表示选了前\(i\)列,第\(2\)行第\(i\)列的格子是第\(j\)个被填 ...
- AtCoder刷题记录
构造题都是神仙题 /kk ARC066C Addition and Subtraction Hard 首先要发现两个性质: 加号右边不会有括号:显然,有括号也可以被删去,答案不变. \(op_i\)和 ...
- Codeforces Round #130 (Div. 2)
A. Dubstep 字符串模拟. string.find()用法 string str; size_t pos = str.find("WUB"); // 返回匹配的第一个位置 ...
- csp退役前的做题计划1(真)
csp退役前的做题计划1(真) 因为我太菜了,所以在第一次月考就会退役,还是记录一下每天做了什么题目吧. 任务计划 [ ] Z算法(Z Algorithm) 9.28 [x] ARC061C たくさん ...
- UVa 10651 Pebble Solitaire(DP 记忆化搜索)
Pebble Solitaire Pebble solitaire is an interesting game. This is a game where you are given a board ...
- UVA 10651 Pebble Solitaire 状态压缩dp
一开始还在纠结怎么表示一个状态,毕竟是一个串.后来搜了一下题解发现了这里用一个整数的前12位表示转态就好了 ,1~o,0~'-',每个状态用一个数来表示,然后dp写起来就比较方便了. 代码: #inc ...
- 【ARC068F】Solitaire
Description 你有一个双端队列和 \(N\) 个数字,先按 \(1\) 到 \(N\) 的顺序每次从任意一端插入当前数字,再进行 \(N\) 次操作每次可以从两端弹出,求有多少种弹出序列 ...
- uva 10651 - Pebble Solitaire(记忆化搜索)
题目链接:10651 - Pebble Solitaire 题目大意:给出一个12格的棋盘,‘o'代表摆放棋子,’-‘代表没有棋子, 当满足’-oo'时, 最右边的棋子可以跳到最左边的位子,而中间的棋 ...
- UVA - 11427 Expect the Expected (概率dp)
Some mathematical background. This problem asks you to compute the expected value of a random variab ...
随机推荐
- ethereum(以太坊)(七)--枚举/映射/构造函数/修改器
pragma solidity ^0.4.10; //枚举类型 contract enumTest{ enum ActionChoices{Left,Right,Straight,Still} // ...
- 图像压缩函数imagecopyresampled
<?php //制作缩略图.图像压缩 //参数1:目的地图像资源(通常指的是画布资源) $dst_image = imagecreatetruecolor(100, 100); $color = ...
- salt demo 环境
demo 环境 安装 virtualBox和vagrant 安装工具包:virtualBox, vagrant 下载 https://github.com/UtahDave/salt-vagrant- ...
- 集合源码分析之 HashSet
一 知识准备 HashSet 是Set接口的实现类,Set存在的最大意义区别于List就是,Set中存放的元素不能够重复,就是不能够有两个相同的元素存放在Set中,那么怎样的两个元素才算是相同的,这里 ...
- Webpack标准配置
let htmlWebpckPlugin= require('html-webpack-plugin');//该组件能将src下面提定的html文件与打包后在js文件打包在一起module.expor ...
- VHDL语法入门学习第一篇
1. 现在先遇到一个VHDL的语法问题,以前没用过VHDL,现在要去研究下,进程(PROCESS) 进程内部经常使用IF,WAIT,CASE或LOOP语句.PROCESS具有敏感信号列表(sensit ...
- Eclipse 创建 Java 项目---Eclipse教程第08课
打开新建 Java 项目向导 通过新建 Java 项目向导可以很容易的创建 Java 项目.打开向导的途径有: 通过点击 "File" 菜单然后选择 New > Java P ...
- Android字体大小怎么自适应不同分辨率?
今天有人问我,android系统不同分辨率,不同大小的手机,字体大小怎么去适应呢?其实字体的适应和图片的适应是一个道理的. 一. 原理如下: 假设需要适应320x240,480x320分辨率.在res ...
- __bridge 使用注意
前奏 在平常开发中,我们可能遇到 CoreFoundation(CF) 框架的对象和 OC 对象之间的类型转换,这时候我们需要 __bridge 来帮忙 注意 : 如果是使用 CF __bridge ...
- 《Cracking the Coding Interview》——第4章:树和图——题目1
2014-03-19 03:30 题目:判断一个二叉树是否为平衡二叉树,即左右子树高度相差不超过1. 解法:递归算高度并判断即可. 代码: // 4.1 Implement an algorithm ...