[ARC053D]2 つの山札
题意:给定排列$a_{1\cdots n},b_{1\cdots n}$,执行以下操作$2n-2$次来生成一个长度为$2n-2$的序列:选择$a,b$之一(选择的序列长度要$\geq2$),删除它的第一个数字并将另一个序列的第一个数字加到生成的序列的末尾,问最后能生成多少种不同的序列
首先是一个转化,画一个$n\times n$的网格,第$i$行的$n-1$条边上的数字为$a_i$,第$i$列的$n-1$条边上的数字为$b_i$,一个生成的序列对应着这个网格上从左上角到右下角的一条路径上的数字

对于$a=\{3,1,4,2,5\},b=\{3,2,4,1,5\}$,题解给了以上这张对应的图
考虑DP,设$f_{i,j}$表示走到$(i,j)$的不同方案数,直接转移就是$f_{i,j}=f_{i-1,j}+f_{i,j-1}$,但如果$a_i=b_j$,那么这样可能产生重复
考虑所有使得$a_{i-k}=b_{j-k}(k\geq1)$的$k$,如果从某个$(i-k,j-k)$走到$(i,j)$只经过这些$(i-k',*)$和$(*,j-k')$,那么一条从$(i-k,j-k)$到$(i,j)$且不碰对角线的路径,沿对角线对称可以得到路径不同但得到数列相同的方案,我们要减去这些方案,即$\sum\limits_{k\geq1}[a_{i-k}=b_{i-k}]f_{i-k,j-k}C_{t-1}$,其中$C_n$是卡特兰数,$t$为当前是第几个满足要求的$k$
答案即为$f_{n,n}$,因为只会有$n$对$a_i=b_j$,所总时间复杂度为$O(n^2)$
#include<stdio.h>
typedef long long ll;
const int mod=1000000007;
int mul(int a,int b){return(ll)a*b%mod;}
int pow(int a,int b){
int s=1;
while(b){
if(b&1)s=mul(s,a);
a=mul(a,a);
b>>=1;
}
return s;
}
int fac[2010],rfac[2010];
void pre(int n){
int i;
fac[0]=1;
for(i=1;i<=n;i++)fac[i]=mul(fac[i-1],i);
rfac[n]=pow(fac[n],mod-2);
for(i=n;i>0;i--)rfac[i-1]=mul(rfac[i],i);
}
int C(int n){return mul(fac[2*n],mul(rfac[n],rfac[n+1]));}
int a[1010],b[1010],f[1010][1010];
int main(){
int n,i,j,k,s;
scanf("%d",&n);
pre(n*2);
for(i=1;i<=n;i++)scanf("%d",a+i);
for(i=1;i<=n;i++)scanf("%d",b+i);
f[1][1]=1;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(i>1||j>1)f[i][j]=(f[i-1][j]+f[i][j-1])%mod;
if(a[i]==b[j]){
s=0;
for(k=1;i-k>0&&j-k>0;k++){
if(a[i-k]==b[j-k])(f[i][j]-=mul(C(s++),f[i-k][j-k]))%=mod;
}
}
}
}
printf("%d",(f[n][n]+mod)%mod);
}
[ARC053D]2 つの山札的更多相关文章
- AT1879 2 つの山札
题面 题解 直接求解比较麻烦,考虑将问题进行转化. 设序列\(a = \{3, 1, 4, 2, 5\}, b = \{3, 2, 4, 1, 5\}\),那么我们构造一个正方形方格,将\(a\)放在 ...
- HDU2063 过山车
过山车 RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做partner和她同坐.但是, ...
- HDOJ 2063 过山车
过山车 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- Xamarin.Android之山有木兮之木有枝,心悦君兮君不知。
Xamarin.Android之山有木兮之木有枝,心悦君兮君不知. 第一步,写项目中的第一个界面. <?xml version="1.0" encoding =" ...
- hdu 2063 过山车(匈牙利算法模板)
http://acm.hdu.edu.cn/showproblem.php?pid=2063 过山车 Time Limit: 1000/1000 MS (Java/Others) Memory ...
- HDU- 2063 过山车
http://acm.hdu.edu.cn/showproblem.php?pid=2063 过山车//我的第一个二分匹配 Time Limit: 1000/1000 MS (Java/Others) ...
- hdoj 2063 过山车【匈牙利算法+邻接矩阵or邻接表】
过山车 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- centos 6+安装山逗斯骚尅特(本文内容来自都比更具帝)
系统支持:CentOS 6+,Debian 7+,Ubuntu 12+ 内存要求:≥128M 关于本脚本 一键安装 Shadowsocks-Python, ShadowsocksR, Shadowso ...
- 大龄剩女四大结局:孤寡 后妈 拉拉 出家 宽带山KDS-宽带山社区-第一城市消费门户
大龄剩女四大结局:孤寡 后妈 拉拉 出家 宽带山KDS-宽带山社区-第一城市消费门户 主题:大龄剩女四大结局:孤寡 后妈 拉拉 出家
随机推荐
- 2017 ACM暑期多校联合训练 - Team 3 1008 HDU 6063 RXD and math (莫比乌斯函数)
题目链接 Problem Description RXD is a good mathematician. One day he wants to calculate: ∑i=1nkμ2(i)×⌊nk ...
- 1、编写第一个java程序--Hello—World
1.下载JDK8.0文件 下载网址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.ht ...
- 阿里分布式开源框架DUBBO 入门+ 进阶+ 项目实战视频教程
史诗级Java/JavaWeb学习资源免费分享 欢迎关注我的微信公众号:"Java面试通关手册"(坚持原创,分享各种Java学习资源,面试题,优质文章,以及企业级Java实战项目回 ...
- python并发编程之threading线程(一)
进程是系统进行资源分配最小单元,线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.进程在执行过程中拥有独立的内存单元,而多个线程共享内存等资源. 系列文章 py ...
- python设计模式之迭代器与生成器详解(五)
前言 迭代器是设计模式中的一种行为模式,它提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示.python提倡使用生成器,生成器也是迭代器的一种. 系列文章 python设计模 ...
- 【51nod1006】simple KMP
原题意看的挺迷糊的,后来看了http://blog.csdn.net/YxuanwKeith/article/details/52351335大爷的题意感觉清楚的多…… 做法也非常显然了,用树剖维护后 ...
- windows 10添加定时任务
1.在搜索栏搜索‘任务计划’ 2.选择任务计划程序,打开 3.创建基本任务 4.输入任务名称 5.选择任务触发周期 6.选择任务触发的具体时间点 7.选择任务需要做的事 8.选择启动程序后,选择具体的 ...
- [ python ] 集合的使用
集合的使用 可变数据类型,他里面的元素必须是不可变的数据类型,无序,不重复. 集合的增删查 集合是没有改这种说法的: (1)集合的元素无序的: (2)集合的元素为不可变类型 增加 add 为集 ...
- EL(表达式)语言的几种运算符
1.EL的基本语法 (1)EL表达式语法:以${开头,以}结束,中间为合法的表达式,具体语法格式如下: ${expression} (2)参数说明:Expression:指定要输出的内容,可以是字符串 ...
- Linux软件安装install命令
install 1.作用 install命令的作用是安装或升级软件或备份数据,它的使用权限是所有用户. 2.格式 (1)install [选项]... 来源 目的地 (2)install [选项]. ...