意甲冠军:

序列p1、p2、p3……pn由1、2、3……n这些数字  现在给出一些条件pi<pj  部条件的排列的个数

思路:

非常easy想到用一条有向的线连接全部的pi和pj  那么就构成了有向无环图(题中说有解所以无环)

又由于pi各不同样  那么题目就变成了有向无环图的拓扑排序的种类数

题目中边数较少  所以可能出现不连通情况  我们先讨论一个连通集合内拓扑排序的种类数

题目中m较小  能够利用状压后的记忆化搜索解决

如今考虑假设知道了A和B两个集合各自的种类数  假设把它们合起来

因为各自种类已知  我们能够把A和B当成有序的排列  那么问题就变成了将|B|个元素插空到|A|个元素中间

这个能够利用dp解决  同一时候n较小  我们能够直接打出表

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define N 45
typedef long long LL; const int mod = (int) 1e9 + 7;
int dp[2][N], f[N][N], in[N], out[N], fa[N], vis[N], qu[N], g[1 << 21];
vector<int> ed[N];
int n, m, ans, top;
struct node {
int id, fa;
bool operator<(const node ff) const {
return fa < ff.fa;
}
} nd[N]; void init() {
for (int i = 1; i <= n; i++) {
in[i] = out[i] = 0;
fa[i] = i;
vis[i] = 0;
ed[i].clear();
}
ans = 1;
top = 0;
} int getf(int x) {
if (x != fa[x])
fa[x] = getf(fa[x]);
return fa[x];
} LL topo(int sta) {
if (g[sta] != -1)
return g[sta];
LL res = 0;
int i, u, j, ss;
for (i = 0; i < top; i++) {
u = qu[i];
if (!vis[u] && !in[u]) {
vis[u] = 1;
ss = ed[u].size();
for (j = 0; j < ss; j++)
in[ed[u][j]]--;
res += topo(sta | (1 << i));
vis[u] = 0;
for (j = 0; j < ss; j++)
in[ed[u][j]]++;
}
}
return g[sta] = res % mod;
} void maketable() {
int i, j, u, v, from, to;
for (i = 1; i < N; i++) {
f[0][i] = 1;
for (j = i; j < N; j++) {
for (v = 1; v <= i + 1; v++)
dp[1][v] = 1;
to = 1;
for (u = 2; u <= j; u++) {
from = (u & 1) ^ 1;
to = u & 1;
for (v = 1; v <= i + 1; v++)
dp[from][v] = (dp[from][v] + dp[from][v - 1]) % mod;
for (v = 1; v <= i + 1; v++)
dp[to][v] = dp[from][v];
}
for (v = 1; v <= i + 1; v++)
dp[to][v] = (dp[to][v] + dp[to][v - 1]) % mod;
f[j][i] = f[i][j] = dp[to][i + 1];
}
}
} int main() {
int i, j, u, v;
maketable();
while (~scanf("%d%d", &n, &m)) {
init();
for (i = 1; i <= m; i++) {
scanf("%d%d", &u, &v);
if (u == v)
continue;
ed[u].push_back(v);
in[v]++;
out[u]++;
u = getf(u);
v = getf(v);
if (u != v)
fa[v] = u;
}
for (i = 1; i <= n; i++) {
nd[i].id = i;
nd[i].fa = getf(i);
}
sort(nd + 1, nd + n + 1);
nd[n + 1].fa = -1;
for (i = 1; i <= n; i = j) {
top = 1;
qu[0] = nd[i].id;
for (j = i + 1; j <= n + 1; j++) {
if (nd[j].fa == nd[i].fa) {
qu[top++] = nd[j].id;
} else {
for (u = 0; u < (1 << top); u++)
g[u] = -1;
g[(1 << top) - 1] = 1;
ans = (LL) ans * (topo(0) * f[i - 1][j - i] % mod) % mod;
break;
}
}
}
printf("%d\n", ans);
}
return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

HDU 4917 Permutation的更多相关文章

  1. HDU 4917 Permutation(拓扑排序 + 状压DP + 组合数)

    题目链接 Permutation 题目大意:给出n,和m个关系,每个关系为ai必须排在bi的前面,求符合要求的n的全排列的个数. 数据规模为n <= 40,m <= 20. 直接状压DP空 ...

  2. HDU 4917 Permutation 拓扑排序的计数

    题意: 一个有n个数的排列,给你一些位置上数字的大小关系.求合法的排列有多少种. 思路: 数字的大小关系可以看做是一条有向边,这样以每个位置当点,就可以把整个排列当做一张有向图.而且题目保证有解,所以 ...

  3. HDU 5753 Permutation Bo (推导 or 打表找规律)

    Permutation Bo 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5753 Description There are two sequen ...

  4. hdu 5753 Permutation Bo 水题

    Permutation Bo 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5753 Description There are two sequen ...

  5. HDU 3811 Permutation 状压dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3811 Permutation Time Limit: 6000/3000 MS (Java/Othe ...

  6. HDU 6628 permutation 1 (暴力)

    2019 杭电多校 5 1005 题目链接:HDU 6628 比赛链接:2019 Multi-University Training Contest 5 Problem Description A s ...

  7. hdu 2583 permutation

    permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  8. HDU 4345 Permutation dp

    Permutation Problem Description There is an arrangement of N numbers and a permutation relation that ...

  9. hdu 5753 Permutation Bo

    这里是一个比较简单的问题:考虑每个数对和的贡献.先考虑数列两端的值,两端的摆放的值总计有2种,比如左端:0,大,小:0,小,大:有1/2的贡献度.右端同理. 中间的书总计有6种可能.小,中,大.其中有 ...

随机推荐

  1. 泛泰A850 (高通8064+720p)刷4.4专用中文recovery TWRP2.7.1.3版

    欢迎关注泛泰非盈利专业第三方开发团队 VegaDevTeam  (本team 由 syhost suky zhaochengw(z大) xuefy(大星星) tenfar(R大师) loogeo cr ...

  2. 算法8-4:Kruskal算法

    Kruskal算法用于计算一个图的最小生成树.这个算法的过程例如以下: 依照边的权重从小到达进行排序 依次将每条边添加到最小生成树中,除非这条边会造成回路 实现思路 第一个步骤须要对边进行排序,排序方 ...

  3. HDU1071 The area 【积分】

    The area Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  4. Python3.2官方文件翻译--课堂笔记和异常是阶级

    6.7备注 有时喜欢Pasca在"录"和C中"数据体"的数据类型很实用.集合一些数据项. 一个空类定义能够清楚地显示: class Employee: pass ...

  5. CodeBlocks暴力恢复默认设置

    昨天,我不知道怎么去CodeBlocks干净的界面使自己都不知道怎么走.然后找到默认设置恢复方法,找不到.然后,我用了一个恢复方法暴力,卸载重装,有一点须要注意.卸载后CodeBlocks的配置文件还 ...

  6. 更具体的描述JNI

    JNI事实上,Java Native Interface缩写,也就是说,java本地接口. 它提供了许多API实现和Java并与其他语言的沟通(主要C&C++). 也许很多人认为Java够劲. ...

  7. Dom4j分解xml

    package cn.com.guju.util; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingExc ...

  8. 重新想象 Windows 8 Store Apps (23) - 文件系统: 文本的读写, 二进制的读写, 流的读写, 最近访问列表和未来访问列表

    原文:重新想象 Windows 8 Store Apps (23) - 文件系统: 文本的读写, 二进制的读写, 流的读写, 最近访问列表和未来访问列表 [源码下载] 重新想象 Windows 8 S ...

  9. Android Bundle类别

    即使在今天发现自己Bundle类不明确,因此,花时间去研究了一下. 依据google官方文件(http://developer.android.com/reference/android/os/Bun ...

  10. 使用 Cordova+Visual Studio 创建跨平台移动应用(3)

    1 背景 本章节是关于Telerik AppBuilder for Visual Studio的. 目前(2014.12)为Telerik公司Telerik Platform的一部分,Telerik ...