HDU 4917 Permutation
意甲冠军:
序列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的更多相关文章
- HDU 4917 Permutation(拓扑排序 + 状压DP + 组合数)
题目链接 Permutation 题目大意:给出n,和m个关系,每个关系为ai必须排在bi的前面,求符合要求的n的全排列的个数. 数据规模为n <= 40,m <= 20. 直接状压DP空 ...
- HDU 4917 Permutation 拓扑排序的计数
题意: 一个有n个数的排列,给你一些位置上数字的大小关系.求合法的排列有多少种. 思路: 数字的大小关系可以看做是一条有向边,这样以每个位置当点,就可以把整个排列当做一张有向图.而且题目保证有解,所以 ...
- HDU 5753 Permutation Bo (推导 or 打表找规律)
Permutation Bo 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5753 Description There are two sequen ...
- hdu 5753 Permutation Bo 水题
Permutation Bo 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5753 Description There are two sequen ...
- HDU 3811 Permutation 状压dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3811 Permutation Time Limit: 6000/3000 MS (Java/Othe ...
- HDU 6628 permutation 1 (暴力)
2019 杭电多校 5 1005 题目链接:HDU 6628 比赛链接:2019 Multi-University Training Contest 5 Problem Description A s ...
- hdu 2583 permutation
permutation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU 4345 Permutation dp
Permutation Problem Description There is an arrangement of N numbers and a permutation relation that ...
- hdu 5753 Permutation Bo
这里是一个比较简单的问题:考虑每个数对和的贡献.先考虑数列两端的值,两端的摆放的值总计有2种,比如左端:0,大,小:0,小,大:有1/2的贡献度.右端同理. 中间的书总计有6种可能.小,中,大.其中有 ...
随机推荐
- 多线程——达到Runnable介面
部分博客(多线程--继承Thread类)介绍了java多线程的第一种实现方法--继承Thread类.这篇博客介绍另外一种方法--实现Runnable接口,并实现run方法. 还用上篇博客的样例.如今用 ...
- Jquery 时间格式化
var TimeObjectUtil;/** * @title 时间工具类 * @note 本类一律违规验证返回false * @author {boonyachengdu@gmail.com} * ...
- Red Gate系列之五 .NET Reflector 7.6.1.824 Edition .NET程序反编译神器(附插件安装教程2012-10-13更新) 完全破解+使用教程
原文:Red Gate系列之五 .NET Reflector 7.6.1.824 Edition .NET程序反编译神器(附插件安装教程2012-10-13更新) 完全破解+使用教程 Red Gate ...
- UVA11100- The Trip, 2007
option=com_onlinejudge&Itemid=8&category=512&page=show_problem&problem=2041"> ...
- C# Windows Phone 8 WP8 开发,将WebClient的DownloadStringCompleted事件改成非同步的awiat方法。
原文:C# Windows Phone 8 WP8 开发,将WebClient的DownloadStringCompleted事件改成非同步的awiat方法. 一般我们在撰写Windows Phone ...
- Hibernate Tomcat JNDI数据源配置(转)
简述: 配置JNDI 查找Tomcat 中server.xml中定义的数据源 步骤: 1. 修改elipse的数据源server.xml 主要修改如下, 1. 添加下面这段Context文本 其中St ...
- 关与 Visual.Assist.X.V10.7.1912的Crack破解补丁(vs 番茄插件的key破解方法)
在win7系统下, 我用的是vs2012版本号. Visual Assist沿用了快10年的界面,最终有了更新,变得更加适合Win8 以及 VS2012的主题风格了 ,这也是以后软件的发展趋势,仅仅是 ...
- [ACM] HDU 3395 Special Fish (最大重量二分图匹配,KM算法)
Special Fish Problem Description There is a kind of special fish in the East Lake where is closed to ...
- 移动web:转盘抽奖(幸运大转盘)
为了获取客户.回馈客户,平台一般会推出抽奖活动类的营销页.因此web页面中,有各式各样的抽奖效果. 格子式(九宫格),背景滚动式(数字/文字/图案),旋转式(转盘),游戏式(砸蛋/拼图...).... ...
- Xamarin.Android 使用 SQLiteOpenHelper 进行数据库操作
一.前言 在手机中进行网络连接不仅是耗时也是耗电的,而耗电却是致命的.所以我们就需要数据库帮助我们存储离线数据,以便在用户未使用网络的情况下也可以能够使用应用的部分功能,而在需要网络连接的功能上采用提 ...