Atcoder Grand Contest 024 E - Sequence Growing Hard(dp+思维)
典型的 Atcoder 风格的计数 dp。
题目可以转化为每次在序列中插入一个 \([1,k]\) 的数,共操作 \(n\) 次,满足后一个序列的字典序严格大于前一个序列,问有多少种操作序列。
显然相同的数可以合并,因为在由相同的数 \(x\) 组成的数段中,在任何位置插入 \(x\),得到的序列都是相同的。
再考虑字典序的问题。你只能序列末尾或者一个 \(<x\) 的数前面插入 \(x\),否则得到的序列的字典序就会 \(\geq\) 原序列的字典序。
但这样问题还是比较棘手,我们还需进一步转化。
我们把操作序列转化为一棵有根树,树上每个节点都是一个二元组 \((val,dfn)\),表示第 \(dfn\) 次操作插入了值为 \(val\) 的数。如果第 \(i\) 次操作将 \(v\) 插在第 \(j\) 次操作插入的数 \(w\) 前面,那么我们就将节点 \((v,i)\) 挂在 \((w,j)\) 下面。新建一个虚拟节点 \((0,0)\),如果在序列末尾插入 \(v\),那么就把 \((v,i)\) 挂在 \((0,0)\) 下面。
由于我们只能在 \(<x\) 的数前面插入 \(x\),因此若 \(y\) 为 \(x\) 的父亲,那么 \(val_y>val_x\),\(dfn_y<dfn_x\)
不妨举个例子,假设有如下的操作序列:
- 向序列中插入数 \(1\),得到序列 \([1]\)。这可看成将点 \((1,1)\) 挂在点 \((0,0)\) 下面。
- 在 \(1\) 前插入 \(3\),得到序列 \([3,1]\)。这可看成将点 \((3,2)\) 挂在点 \((1,1)\) 下面。
- 在序列末尾插入 \(2\),得到序列 \([3,1,2]\)。这可看成将点 \((2,3)\) 挂在点 \((0,0)\) 下面。
- 在 \(1\) 再插入一个 \(3\),得到序列 \([3,3,1,2]\)。这可看成将点 \((3,4)\) 挂在点 \((1,1)\) 下面。
- 在 \(1\) 前插入一个 \(2\),得到序列 \([3,3,2,1,2]\)。这可看成将点 \((2,5)\) 挂在点 \((1,1)\) 下面。
- 在第二个 \(3\) 前插入一个 \(4\),得到序列 \([3,4,3,2,1,2]\)。这可看成将点 \((4,6)\) 挂在点 \((3,4)\) 下面。
这样 \(6\) 次操作下来,我们得到了一棵 \(7\) 个节点的树,如下图:

一种操作序列恰对应一棵树,一棵满足条件的树也对应一种操作序列。因此问题转化为有多少个满足条件的树。
这就可以直接 \(dp\) 了。我们设 \(dp_{i,j}\) 表示有多少个以 \(i\) 为节点的树,根节点的 \(val\) 为 \(j\)。
考虑转移,对于 \(i>1\),假设根节点的 \(dfn\) 为 \(1\),那么根节点必定有个儿子,其 \(dfn\) 为 \(2\)。我们就枚举这棵子树的大小 \(l\) 和根节点的 \(val\) —— \(v\)。确定这棵子树的形态的方案数为 \(dp_{l,v}\),将这棵子树中所有节点的 \(dfn\) 值定好的方案数为 \(C_{n-2}^{k-1}\)(从 \(3\) 到 \(n\) 这 \(n-2\) 个数中中选择 \(k-1\) 个数),填好剩余部分的方案数为 \(dp_{i-l,j}\)。因此有转移方程:
\]
后面那个 \(\sum\) 可以用前缀和优化掉。时间复杂度 \(\mathcal O(n^2k)\)
/*
Contest: -
Problem: Atcoder Grand Contest 024 E
Author: tzc_wk
Time: 2020.7.22
*/
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a) a.begin(),a.end()
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1 y1010101010101
#define y0 y0101010101010
#define int long long
typedef pair<int,int> pii;
inline int read(){
int x=0,neg=1;char c=getchar();
while(!isdigit(c)){
if(c=='-') neg=-1;
c=getchar();
}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x*neg;
}
int n=read(),k=read(),m=read();
int C[305][305],s[305][305],dp[305][305];
signed main(){
fz(i,0,300){
C[i][0]=1;
fz(j,1,i) C[i][j]=(C[i-1][j]+C[i-1][j-1])%m;
}
// printf("%d\n",C[5][3]);
fz(i,0,k) dp[1][i]=1;
fd(i,k,0) s[1][i]=(s[1][i+1]+dp[1][i])%m;
fz(i,2,n+1){
fz(j,0,k)
fz(l,1,i-1)
dp[i][j]=(dp[i][j]+C[i-2][l-1]*dp[i-l][j]%m*s[l][j+1]%m)%m;
fd(j,k,0) s[i][j]=(s[i][j+1]+dp[i][j])%m;
}
printf("%lld\n",dp[n+1][0]);
return 0;
}
Atcoder Grand Contest 024 E - Sequence Growing Hard(dp+思维)的更多相关文章
- AtCoder Grand Contest 019 B - Reverse and Compare【思维】
AtCoder Grand Contest 019 B - Reverse and Compare 题意:给定字符串,可以选定任意i.j且i<=j(当然i==j时没啥卵用),然后翻转i到j的字符 ...
- [AtCoder Grand Contest 024 Problem E]Sequence Growing Hard
题目大意:考虑 N +1 个数组 {A0,A1,…,AN}.其中 Ai 的长度是 i,Ai 内的所有数字都在 1 到 K 之间. Ai−1 是 Ai 的子序列,即 Ai 删一个数字可以得到 Ai−1. ...
- Atcoder Grand Contest 024
A 略 B 略 C 略 D(构造分形) 题意: 给出一个由n个点的组成的树,你可以加一些点形成一个更大的树.对于新树中的两个点i和j,如果以i为根的树与以j为根的树是同构的那么i和j颜色可以相同.问最 ...
- Atcoder Grand Contest 005 E - Sugigma: The Showdown(思维题)
洛谷题面传送门 & Atcoder 题面传送门 记先手移动棋子的树为红树,后手移动棋子的树为蓝树. 首先考虑一个性质,就是如果与当前红色棋子所在的点相连的边中存在一条边,满足这条边的两个端点在 ...
- Atcoder Grand Contest 022 E - Median Replace(dp)
Atcoder 题面传送门 & 洛谷题面传送门 首先考虑对于固定的 01 串怎样计算它是否可以通过将三个连续的 \(0\) 或 \(1\) 替换为其中位数得到.我们考虑单调栈,新建一个栈,栈底 ...
- Atcoder Grand Contest 002 F - Leftmost Ball(dp)
Atcoder 题面传送门 & 洛谷题面传送门 这道 Cu 的 AGC F 竟然被我自己想出来了!!!((( 首先考虑什么样的序列会被统计入答案.稍微手玩几组数据即可发现,一个颜色序列 \(c ...
- Atcoder Grand Contest 039C(容斥原理,计数DP)
//每次操作相当于将最低位取反加到最高位(N~1位)#define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace s ...
- Atcoder Grand Contest 037C(贪心,优先队列,思维)
#define HAVE_STRUCT_TIMESPEC//编译器中time.h和phread.h头文件中timespec结构体重名,故加此行#include<bits/stdc++.h> ...
- AtCoder Grand Contest 031 简要题解
AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本质不同子序列的个数模\(10^9+7\). ...
随机推荐
- 力扣 - 剑指 Offer 39. 数组中出现次数超过一半的数字
题目 剑指 Offer 39. 数组中出现次数超过一半的数字 思路1(排序) 因为题目说一定会存在超过数组长度一半的一个数字,所以我们将数组排序后,位于length/2位置的一定是众数 代码 clas ...
- 【UE4 C++】 外部图片读取、Texture 保存 png
蓝图版 导入外部图片 file://E:/UE___Projects_Test/MyProjectAAA/Plugins/WXimage.jpg 导出图图片 一般导出 .hdr 文件 导出 png 设 ...
- 理解ASP.NET Core - 路由(Routing)
注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 Routing Routing(路由):更准确的应该叫做Endpoint Routing,负责 ...
- 5.31日 Scrum Metting
日期:2021年5月31日 会议主要内容概述:讨论草稿箱前后端接口,讨论账单页面设计. 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 徐宇龙 后端 文件导入功能 ...
- [no code][scrum meeting] Alpha 2
项目 内容 会议时间 2020-04-07 会议主题 功能规格说明书review 会议时长 30min 参会人员 OCR组(肖思炀,赵涛)和产品经理 $( "#cnblogs_post_bo ...
- 开关电源(DC-DC)与LDO电源的区别---纹波
https://blog.csdn.net/edadoc2013/article/details/78435775
- Win10下C语言转8086汇编
目录 Win10下C语言转8086汇编 简介 开始 写C代码 转换成汇编代码 Win10下C语言转8086汇编 简介 最近学习<王爽汇编>,然后突发奇想,想一边写C语言用编译器将其翻译成汇 ...
- 这一次,解决Flutter Dialog的各种痛点!
前言 Q:你一生中闻过最臭的东西,是什么? A:我那早已腐烂的梦. 兄弟萌!!!我又来了! 这次,我能自信的对大家说:我终于给大家带了一个,能真正帮助大家解决诸多坑比场景的pub包! 将之前的flut ...
- 『学了就忘』Linux基础命令 — 20、文件操作的相关命令
目录 1.touch 命令 2.stat命令 3.cat命令 4.more命令 5.less命令 6.head命令 7.tail命令 1.touch 命令 touch命令用于创建空文件或修改文件时间, ...
- Pycharm的安装简介
Pycharm 1. Pycharm简介 PyCharm是由JetBrains打造的一款Python IDE,VS2010的重构插件Resharper就是出自JetBrains之手.同时支持Googl ...