bzoj 4824: [Cqoi2017]老C的键盘
Description
Input
Output
Sample Input
Sample Output
共5个按键,第1个按键比第2个按键矮,第1个按键比第3个按键高,第2个按键比第4个
按键高,第2个按键比第5个按键矮。
这5个按键的高度排列可以是 2,4,1,3,5 , 3,4,1,2,5 , 3,4,2,1,5 。
HINT
Source
之前看到这个题的时候毫无想法,现在看起来和实验比较的做法差不多(这个题好像有原题,bzoj 2111 和 bzoj 3167)
woc这原来都是一个题,但是这题我的做法和实验比较的做法差不多;
首先题目给了一棵完全二叉树,然后给了父亲和儿子的关系,那么我们设dp[i][j],表示i的子树内,i的排名为j的方案数;
然后做法流程和实验比较类似,合并(x,i),(y,j)时首先分情况枚举合并后x的rank为k;
1.x>y;
那么k从i枚举到i+j-1,然后就相当于这样一个问题:
前半段有k-1个盒子,i-1个红球,k-1-(i-1)个蓝球,后半段有size[x]+size[y]-k个盒子,有size[x]-i个红球,...个蓝球,
红蓝球都有顺序;
然后问每个盒子都填了一个球,而且红蓝球的内部顺序不变的方案数:
那么转移就是:
2.x<y
k就是从i+j,枚举到i+size[y],然后转移是一模一样的;
然后具体实现方法和实验比较一样。。。
//MADE BY QT666
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=1050;
const int Mod=1e9+7;
ll c[N][N],size[N],dp[N][N],g[N],head[N],to[N],nxt[N],type[N],cnt,n;
char s[N];
void lnk(int x,int y,int z){
to[++cnt]=y,nxt[cnt]=head[x],type[cnt]=z,head[x]=cnt;
}
void dfs(int x){
size[x]=1;
for(int p=head[x];p;p=nxt[p]){
int y=to[p],flg=type[p];dfs(y);
if(flg==1){
if(size[x]==1){
for(int i=1;i<=size[y];i++){
for(int j=1;j<=i;j++) (dp[x][j]+=dp[y][i])%=Mod;
}
size[x]+=size[y];
for(int i=1;i<=size[x];i++) g[i]=dp[x][i];
}
else{
int tot=size[x]+size[y];
for(int i=1;i<=size[x];i++){
for(int j=1;j<=size[y];j++){
for(int k=i;k<=i+j-1;k++){
(g[k]+=dp[x][i]*dp[y][j]%Mod*c[k-1][i-1]%Mod*c[tot-k][size[x]-i]%Mod)%=Mod;
}
}
}
size[x]+=size[y];
for(int i=1;i<=size[x];i++) dp[x][i]=g[i];
}
}
else {
if(size[x]==1){
for(int i=1;i<=size[y];i++){
for(int j=i;j<=size[y];j++) (dp[x][j+1]+=dp[y][i])%=Mod;
}
size[x]+=size[y];
for(int i=1;i<=size[x];i++) g[i]=dp[x][i];
}
else{
int tot=size[x]+size[y];
for(int i=1;i<=size[x];i++){
for(int j=1;j<=size[y];j++){
for(int k=i+j;k<=i+size[y];k++){
(g[k]+=dp[x][i]*dp[y][j]%Mod*c[k-1][i-1]%Mod*c[tot-k][size[x]-i]%Mod)%=Mod;
}
}
}
size[x]+=size[y];
for(int i=1;i<=size[x];i++) dp[x][i]=g[i];
}
}
}
if(size[x]==1) dp[x][1]=1;
memset(g,0,sizeof(g));
}
int main(){
scanf("%lld",&n);scanf("%s",s+1);
for(int i=2;i<=n;i++){
if(s[i-1]=='<') lnk(i/2,i,1);
if(s[i-1]=='>') lnk(i/2,i,2);
}
for(int i=0;i<=n;++i) c[i][0]=1;
for(int i=1;i<=n;++i)
for(int j=1;j<=i;++j){
c[i][j]=(c[i-1][j-1]+c[i-1][j])%Mod;
}
dfs(1);ll ans=0;
for(int i=1;i<=size[1];i++) (ans+=dp[1][i])%=Mod;
printf("%lld\n",ans);
return 0;
}
bzoj 4824: [Cqoi2017]老C的键盘的更多相关文章
- BZOJ 4824 [Cqoi2017]老C的键盘 ——树形DP
每一个限制条件相当于一条有向边, 忽略边的方向,就成了一道裸的树形DP题 同BZOJ3167 唯一的区别就是这个$O(n^3)$能过 #include <map> #include < ...
- bzoj 4824: [Cqoi2017]老C的键盘【树形dp】
参考:https://www.cnblogs.com/FallDream/p/bzoj4824.html 画一画就会发现关系形成了一棵二叉树(其实看到n-1就能想到 然后dp,设f[i][j]为点i在 ...
- [BZOJ4824][Cqoi2017]老C的键盘 树形dp+组合数
4824: [Cqoi2017]老C的键盘 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 218 Solved: 171[Submit][Statu ...
- [BZOJ4824][CQOI2017]老C的键盘(树形DP)
4824: [Cqoi2017]老C的键盘 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 193 Solved: 149[Submit][Statu ...
- [CQOI2017]老C的键盘
[CQOI2017]老C的键盘 题目描述 额,网上题解好像都是用的一大堆组合数,然而我懒得推公式. 设\(f[i][j]\)表示以\(i\)为根,且\(i\)的权值为\(j\)的方案数. 转移: \[ ...
- bzoj 4822: [Cqoi2017]老C的任务
4822: [Cqoi2017]老C的任务 练手速... #include <iostream> #include <cstdio> #include <cstring& ...
- bzoj 4823: [Cqoi2017]老C的方块 [最小割]
4823: [Cqoi2017]老C的方块 题意: 鬼畜方块游戏不解释... 有些特殊边,有些四个方块组成的图形,方块有代价,删掉一些方块使得没有图形,最小化代价. 比较明显的最小割,一个图形中必须删 ...
- [bzoj4824][Cqoi2017]老C的键盘
来自FallDream的博客,未经允许,请勿转载,谢谢. 老 C 是个程序员. 作为一个优秀的程序员,老 C 拥有一个别具一格的键盘,据说这样可以大幅提升写程序的速度,还能让写出来的程序在某种 ...
- [bzoj4824][洛谷P3757][Cqoi2017]老C的键盘
Description 老 C 是个程序员. 作为一个优秀的程序员,老 C 拥有一个别具一格的键盘,据说这样可以大幅提升写程序的速度,还能让写出来的程序 在某种神奇力量的驱使之下跑得非常快.小 Q 也 ...
随机推荐
- 《java.util.concurrent 包源码阅读》22 Fork/Join框架的初体验
JDK7引入了Fork/Join框架,所谓Fork/Join框架,个人解释:Fork分解任务成独立的子任务,用多线程去执行这些子任务,Join合并子任务的结果.这样就能使用多线程的方式来执行一个任务. ...
- C# 通过url地址获取页面内容
using System.Net; using System.IO; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(" ...
- (译)学习JavaScript闭包
原文地址:https://medium.freecodecamp.org/lets-learn-javascript-closures-66feb44f6a44 闭包是JavaScript中一个基 ...
- 2017计算机学科夏令营上机考试-C:岛屿面积
总时间限制: 1000ms 内存限制: 65536kB 描述 用一个n*m的二维数组表示地图,1表示陆地,0代表海水,每一格都表示一个1*1的区域.地图中的格子只能横向或者纵向连接(不能对角连接) ...
- LogCook 一个简单实用的Android日志管理工具
众所周知,日志的管理是软件系统很重要的一部分,千万不可忽略其重要性.完整的日志将会在系统维护中起着异常重要的作用,就好像磨刀不误砍柴工一样,日志就像对系统进行分析的工具,工具便捷了,对系统分析起来就能 ...
- Ubuntu下编译Bilibili/ijkplayer
在做Android客户端视频播放器的过程中熟悉ijkplayer.他在视频支持协议上要比Android原生的mediaplayer做的要好.因此,自己也基于Bilibili/ijkplayer的重新编 ...
- Python入门 - 生成随机数
生成随机数是编程中经常用到的功能,下面讲几种常用的随机函数randint,uniform, randrange: 一.生成随机整数 randint import random a = random. ...
- 问题记录-运行Tomcat,项目程序没有响应
问题描述:运行Tomcat,项目程序没有响应原因在于 修改成一致路径即可解决.
- TCP/IP协议栈 --- 网络层(IP 首部 和分片)
IP 是TCP/IP协议栈中重要的层次, TCP UDP ICMP IGMP都是依赖IP层进行传输的.首先它是一种不可靠,无连接的协议.不可靠:它不保证IP包能正确到达目的地,无连接:表示IP并不会维 ...
- openstack pike 集群高可用 安装 部署 目录汇总
# openstack pike 集群高可用 安装部署#安装环境 centos 7 史上最详细的openstack pike版 部署文档欢迎经验分享,欢迎笔记分享欢迎留言,或加QQ群663105353 ...