http://www.lydsy.com/JudgeOnline/problem.php?id=4013 (题目链接)

题意

  给出$n$个数的$m$个大小关系,问它们之间可以形成的单调不降的序列有多少种。

Solution

  首先,因为等于号相连的两个数位置互换不会产生新的方案,我们先用并查集把用等号相连的点全部缩成一个。如果此时的图中出现了环,那么答案为$0$。考虑答案不为$0$的情况怎么处理。此时的图已经成为了一个DAG,我们需要在上面统计方案。容易发现,对于一个点,有分有合,合的情况很好处理,分的情况就很尴尬了,什么?你说每一个点只有一条入边?(哔了狗了)。因为并查集缩点后整个图已经变成了一棵树,我们考虑如何进行树形dp。

  $f[x][i]$表示在$x$的子树中,组成的序列用$<$相连的等价类个数为$i$个的序列方案,其中等价类就表示由等号相连的一坨数。不妨设$y$是$x$的某个儿子,那么转移:

\begin{aligned}  g[i+l]=f[x][i]*f[y][j]*\binom{i-1+l}{j-1}*\binom{j-1}{k-l}   \end{aligned}

  其中$i\in[1,size[x]]$,$j\in[1,size[y]]$,$l\in[max(0,k-j+1),k]$。$g$是一个临时的存储答案的数组。$l$是我们枚举的$y$所贡献的等价类,那么剩下的$k-l$就是$y$中与原本$x$中相等的数的个数。$x$永远排在序列首位而且不会与任意一个数相等。$\binom{i-1+l}{j-1}$表示两个无相对关系的已经排序好的序列合并为一个序列的方案。$\binom{j-1}{k-l}$表示在$x$的$j-1$个数中选出与$y$的$k-l$个数相等的数的方案。

细节

  可能是个森林,所以用一个超级源点连向若干根节点。

代码

// bzoj4013
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define inf (1ll<<30)
#define MOD 1000000007
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=200;
LL C[maxn][maxn],f[maxn][maxn],g[maxn];
int head[maxn],size[maxn],vis[maxn],fa[maxn],r[maxn],n,m,c,cnt,sum;
struct data {int u,v;}a[maxn];
struct edge {int to,next;}e[maxn]; int find(int x) {
return x==fa[x] ? x : fa[x]=find(fa[x]);
}
void link(int u,int v) {
e[++cnt]=(edge){v,head[u]};head[u]=cnt;
}
bool bfs() {
queue<int> q;q.push(0);
int tot=0;
while (!q.empty()) {
int x=q.front();q.pop();tot++;
for (int i=head[x];i;i=e[i].next)
if (!--r[e[i].to]) q.push(e[i].to);
}
return tot==sum+1;
}
void dfs(int x) {
vis[x]=f[x][1]=size[x]=1;
for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to]) {
int y=e[i].to;dfs(y);
for (int j=1;j<=size[x];j++) {
if (!f[x][j]) continue;
for (int k=1;k<=size[y];k++) {
if (!f[y][k]) continue;
for (int l=max(0,k-j+1);l<=k;l++)
(g[j+l]+=f[x][j]*f[y][k]%MOD*C[j+l-1][j-1]%MOD*C[j-1][k-l]%MOD)%=MOD;
}
}
size[x]+=size[e[i].to];
for (int i=1;i<=size[x];i++) f[x][i]=g[i],g[i]=0;
}
}
int main() {
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) fa[i]=i;
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;
for (int u,v,i=1;i<=m;i++) {
char ch[2];scanf("%d%s%d",&u,ch,&v);
if (ch[0]=='=') if (find(u)!=find(v)) fa[find(u)]=find(v);
if (ch[0]=='<') a[++c]=(data){u,v};
}
for (int i=1;i<=c;i++) {
int u=find(a[i].u),v=find(a[i].v);
link(u,v);r[v]++;
}
for (int i=1;i<=n;i++) if (fa[i]==i) {
sum++;
if (!r[i]) link(0,i),r[i]++;
}
if (!bfs()) {puts("0");return 0;}
dfs(0);
int ans=0;
for (int i=1;i<=n+1;i++) (ans+=f[0][i])%=MOD;
printf("%d",ans);
return 0;
}

【bzoj4013】 HNOI2015—实验比较的更多相关文章

  1. [BZOJ4013][HNOI2015]实验比较(树形DP)

    4013: [HNOI2015]实验比较 Time Limit: 5 Sec  Memory Limit: 512 MBSubmit: 756  Solved: 394[Submit][Status] ...

  2. BZOJ4013 : [HNOI2015]实验比较

    首先用并查集将等号缩点,然后拓扑排序判断有没有环,有环则无解,否则通过增加超级源点$0$,可以得到一棵树. 设$f[x][y]$表示$x$子树里有$y$种不同的数字的方案数,由底向上DP. 对于当前点 ...

  3. 【BZOJ4013】[HNOI2015]实验比较(动态规划)

    [BZOJ4013][HNOI2015]实验比较(动态规划) 题面 BZOJ 洛谷 题解 看题目意思就是给你一棵树,连边表示强制顺序关系.然后你要给点染色,在满足顺序关系的情况下,将序列染成若干个颜色 ...

  4. 4013: [HNOI2015]实验比较

    4013: [HNOI2015]实验比较 链接 分析: 首先把等号用并查集合并起来. 由于只存在最多一个质量不比i差的数,发现这是森林.若x<y,连边x->y.于是建虚拟根节点0. 然后树 ...

  5. bzoj 4013: [HNOI2015]实验比较

    Description 小D 被邀请到实验室,做一个跟图片质量评价相关的主观实验.实验用到的图片集一共有 N 张图片,编号为 1 到 N.实验分若干轮进行,在每轮实验中,小 D会被要求观看某两张随机选 ...

  6. [HNOI2015]实验比较

    Description 小D 被邀请到实验室,做一个跟图片质量评价相关的主观实验.实验用到的图片集一共有 N 张图片,编号为 1 到 N.实验分若干轮进行,在每轮实验中,小 D会被要求观看某两张随机选 ...

  7. P3240 [HNOI2015]实验比较 树形DP

    \(\color{#0066ff}{ 题目描述 }\) 小D 被邀请到实验室,做一个跟图片质量评价相关的主观实验.实验用到的图片集一共有 \(N\) 张图片,编号为 \(1\) 到\(N\).实验分若 ...

  8. luogu P3240 [HNOI2015]实验比较

    传送门 首先根据题目条件,题目中如果是=的点可以缩起来,然后\(a<b\)连边\(a\rightarrow b\),而且所有点入度为最多1,那么判掉有环的不合法情况,题目中的依赖关系就是一颗外向 ...

  9. 【BZOJ】4013: [HNOI2015]实验比较

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4013 中第i 条涉及的图片对为(KXi, Xi),判断要么是KXi < Xi ,要么 ...

随机推荐

  1. Robot的使用

    在Java中,有一个类,非常神奇,它能帮助你完成某些任务,例如:打开笔记本/QQ等. 今天,我就说一下Robot类的使用方法吧,做一个打开记事本的小程序. 1.准备工作 JDK:不知道的别看了 开发工 ...

  2. Vue Cli 中使用 Karma / Chrome 执行样式相关单元测试

    在 GearCase 开源项目 中,我使用了 Vue Cli 的默认测试框架.因此和样式相关的东西,都无法进行测试.因为它并不类似于无头浏览器,而是存在于虚拟内存之中. 现状 在如下 button.s ...

  3. HackRF 升级固件到新版本

    本文内容.开发板及配件仅限用于学校或科研院所开展科研实验! 淘宝店铺名称:开源SDR实验室 HackRF链接:https://item.taobao.com/item.htm?spm=a1z10.1- ...

  4. 手动搭建一个webpack+react笔记

    { "name": "lottery", "version": "1.0.0", "description&q ...

  5. 【每日scrum】第一次冲刺day2

    和小伙伴一起找地图 ,学习了mapinfo地图格式的基本知识,数据和图像分开存储

  6. 我对git的认识

    Git 真的是不了解 也没听说过git 所以真的不知道从何谈起 所以就参考度娘啦! Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常大的项目版本管理.Git 是 Linus To ...

  7. 项目Beta冲刺(团队)总结

    团队成员及分工 姓名 学号 分工 陈家权 031502107 前端(消息模块) 赖晓连 031502118 前端(问答模块) 雷晶 031502119 服务器 林巧娜 031502125 前端(首页模 ...

  8. BNUOJ 52303 Floyd-Warshall Lca+bfs最短路

    题目链接: https://www.bnuoj.com/v3/problem_show.php?pid=52303 Floyd-Warshall Time Limit: 60000msMemory L ...

  9. 【流程图】购物车、三级菜单、sed替换

  10. Prism6下的MEF:第一个Hello World

    最近看书比较多,正好对过去几年的软件开发做个总结.写这个的初衷只是为了简单的做一些记录. 前言 复杂的应用程序总是面临很多的页面之间的数据交互,怎样创建松耦合的程序一直是多数工程师所思考的问题.诸如依 ...