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. JavaScript判断对象是否是NULL(转)

    写js经常会遇到非空判断,看了你不就像风一样的文章 自己没有做总结,特地转载.很有帮助 function isEmpty(obj) { // 检验 undefined 和 null if (!obj ...

  2. css忽略某一层的存在:pointer-events:none

    其实早知道这个属性,但是一直没有去研究过.今天正好在twitter看到这个词,就去研究了下,正好解决了目前遇到的一个小难题,所以分享下.嗯,其实这是个比较简单的CSS3属性. 在某个项目中,很多元素需 ...

  3. No.1010_第七次团队会议

    渺茫的前景 今天大家都很失望,一来昨天的问题还是继续存在着,仍然没有完成.二来,我们看了一下其余几个组的界面,对自己有些难过. 我们组确实存在人手少的问题,这几天我还因为挑战杯的事情缺席了两天,感觉内 ...

  4. 进阶系列(2)—— C#集合

    一.集合介绍 集合是.NET FCL(Framework Class Library)的重要组成部分,我们平常撸C#代码时免不了和集合打交道,FCL提供了丰富易用的集合类型,给我们撸码提供了极大的便利 ...

  5. 手机访问本地php项目遇到的问题及解决

    做html5的本地应用要调试后台,学了下php 按照和连j2ee的时候一样,电脑发射wifi,ipconfig..等等  发现tomcat的可以访问,apache的不能访问,搜索好久,没找到解答, j ...

  6. 【DL.AI】《Structuring Machine Learning Projects》笔记

    一.改进模型的几个方法 Collect more data Collect more diverse training set Train algorithm longer with gradient ...

  7. # 团队UML设计

    团队信息 学号 姓名 博客链接 124 王彬(组长) 点击这里 206 赵畅 点击这里 215 胡展瑞 点击这里 320 李恒达 点击这里 131 佘岳昕 点击这里 431 王源 点击这里 206 陈 ...

  8. sprintf函数 %6.2f

    %6.2f6表示数据表示至少6位,后面的.2表示小数点后保留两位 比如2342.123415用这个表示的话,结果就是2342.12如果不足六位就会在前面补空格超过六位的话正常显示 代码例子:int m ...

  9. BeTa阶段Day4

    一.提供当天站立式会议照片一张 二.每个人的工作 1.讨论项目每个成员的昨天进展 刘阳航:优化障碍物生成. 林庭亦:调整难度设置. 郑子熙:改进UI,美化界面. 陈文俊:优化代码结构. 2.讨论项目每 ...

  10. 使用 oracle pipelined 返回一个结果集;

    1.使用 create or replace package refcursor_pkg is -- Author : mr.yang -- Created : 5/14/2017 5:13:42 P ...