意甲冠军:

序列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. Android_模拟时钟内时针、分针触摸转动

    最近实现了android里的一个机能,在activity里面画了一个模拟的时针,然后触摸上面的时针跟分针可以实现调时间的功能. 其实,说起原来来还是挺简单的,但是我花了将近一周的时间才全部实现,有点惭 ...

  2. word2vec 中的数学原理具体解释(四)基于 Hierarchical Softmax 的模型

      word2vec 是 Google 于 2013 年开源推出的一个用于获取 word vector 的工具包,它简单.高效,因此引起了非常多人的关注.因为 word2vec 的作者 Tomas M ...

  3. mysql 开放的telnet

    两步开幕mysql远程连接 一个,登录mysql # mysql -uroot -p 两,配置远程连接 mysql > GRANT ALL PRIVILEGES ON *.* TO 'user1 ...

  4. 恢复js文件在windows默认打开方式

    解决办法: 运行 regedit 打开注册表编辑器,定位 "HKEY_CLASSES_ROOT" > ".js" 这一项,双击默认值将数值数据改为&quo ...

  5. ThinkPHP 连接Oracle的配置写法,(使用Oci扩展而非PDO的写法)

    測试了非常多遍,TP官网根本就没有给出正确的写法,并且网上搜索到的全都是错误的. 跟踪代码.终于找出了正确的配置写法,备份例如以下.(by default7#zbphp.com) 'DB_TYPE' ...

  6. 关于Relay Log无法自己主动删除的问题(Neither --relay-log nor --relay-log-index were used)

    今天查看mysql err日志.发现mysql重新启动时总会有例如以下日志出现: [Warning] Neither --relay-log nor --relay-log-index were us ...

  7. ACM/ICPM2014鞍山现场赛D Galaxy (HDU 5073)

    题目链接:pid=5073">http://acm.hdu.edu.cn/showproblem.php?pid=5073 题意:给定一条线上的点,然后能够去掉当中的m个,使剩下的到重 ...

  8. vb实现多用户登录

    利用vb实现多用户登录,主要是将vb与数据库实现链接,这个问题在作品展中我们的软件“天天迹录”的登录时用到,但是当时自己只是知道有这么个功能,但是那些代码的含义并不明白,在3个月后的我又有机会接触到它 ...

  9. Android_declare-styleable_自己定义控件的属性

    1.简单实例 (1).在res/values文件下定义一个attrs.xml文件 <? xml version="1.0" encoding="utf-8" ...

  10. atitit.标准时间格式 相互转换 秒数 最佳实践

    atitit.标准时间格式 相互转换 秒数 最佳实践 例如00:01:19 转换为秒数  79,,and互相转换 一个思路是使用div 60 mod...只是麻烦的... 更好的方法是使用stamp ...