Description

现在有n个人要排成一列,编号为1->n 。但由于一些不明原因的关系,人与人之间可能存在一些矛盾关系,具体有m条矛盾关系(u,v),表示编号为u的人想要排在编号为v的人前面。要使得队伍和谐,最多不能违背k条矛盾关系(即不能有超过k条矛盾关系(u,v),满足最后v排在了u前面)。问有多少合法的排列。答案对10^9+7取模。

Input

输入文件名为count.in。
第一行包括三个整数n,m,k。
接下来m行,每行两个整数u,v,描述一个矛盾关系(u,v)。
保证不存在两对矛盾关系(u,v),(x,y),使得u=x且v=y 。

Output

输出文件名为count.out。
输出包括一行表示合法的排列数。

Sample Input

输入1:

4 2 1
1 3
4 2

输入2:

10 12 3
2 6
6 10
1 7
4 1
6 1
2 4
7 6
1 4
10 4
10 9
5 9
8 10

Sample Output

输出1:

18

输出2:

123120

Data Constraint

对于30%的数据,n<=10
对于60%的数据,n<=15
对应100%的数据,n,k<=20,m<=n*(n-1),保证矛盾关系不重复。

Solution

  • 看到数据范围,显然就是状压DP了。

  • 设 F[s][i]F[s][i] 表示已经选了的人的集合为 ss 、已经违背了 ii 条矛盾关系 的 合法排列数。

  • 转移时枚举将要选的人,处理出会产生的矛盾关系即可。

  • 那么如何快速处理出将会产生的矛盾关系呢?

  • 考虑预处理出 a[x]a[x] 表示排在 xx 以前会有矛盾的人的集合,

  • 那么与 ss & 的值二进制的 1 的个数就是所求的数量了。

  • 时间复杂度为 O(2N∗N∗K)O(2^N*N*K) 。

Code

#include<cstdio>
using namespace std;
const int mo=1e9+7;
int n,m,k,ans;
int a[21],g[1<<20],p[21],f[1<<20][21];
inline int read()
{int X=0,w=1; char ch=0;while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();return X*w;
}
inline void dfs(int x,int y,int z)
{if(z>n) return;g[x]=y;dfs(x,y,z+1);dfs(x+p[z],y+1,z+1);
}
int main()
{n=read(),m=read(),k=read();for(int i=p[0]=1;i<=n;i++) p[i]=p[i-1]<<1;dfs(0,0,0);for(int i=1;i<=m;i++){int x=read(),y=read();a[y]|=p[x-1];}f[0][0]=1;for(int s=0;s<p[n];s++)for(int j=1;j<=n;j++)if(p[j-1]&s){int sum=g[s&a[j]];for(int i=sum;i<=k;i++) f[s][i]=(f[s][i]+f[s-p[j-1]][i-sum])%mo;}for(int i=0;i<=k;i++) ans=(ans+f[p[n]-1][i])%mo;printf("%d",ans);return 0;
}

JZOJ 5230. 【NOIP2017模拟A组模拟8.5】队伍统计相关推荐

  1. JZOJ 5372. 【NOIP2017提高A组模拟9.17】猫

    Description 信息组最近猫成灾了!隔壁物理组也拿猫没办法.信息组组长只好去请神刀手来帮他们消灭猫.信息组现在共有n 只猫(n 为正整数),编号为1 到n,站成了一个环,第i 只猫的左边是第i ...

  2. JZOJ 5392. 【NOIP2017提高A组模拟10.5】Lucky Transformation

    Description Input Output Sample Input 7 2 2343223 4 1 2234 Sample Output 2243233 2334 Data Constrain ...

  3. JZOJ 100041. 【NOIP2017提高A组模拟7.12】列车调度

    Description Input Output Sample Input Sample1: 3 1 2 3 Sample2: 9 1 3 2 4 8 6 9 5 7 Sample Output Sa ...

  4. JZOJ 100026. 【NOIP2017提高A组模拟7.7】图

    Description 有一个n个点n条边的有向图,每条边为< i,f(i),w(i)>,意思是i指向f(i)的边权为w(i)的边,现在小A想知道,对于每个点的si和mi. si:由i出发 ...

  5. JZOJ 5371. 【NOIP2017提高A组模拟9.17】组合数问题

    Description 定义"组合数"S(n,m)代表将n 个不同的元素拆分成m 个非空集合的方案数.举个例子,将{1,2,3}拆分成2 个集合有({1},{2,3}),({2},{1,3}),({3 ...

  6. JZOJ 100047. 【NOIP2017提高A组模拟7.14】基因变异

    Description 21 世纪是生物学的世纪,以遗传与进化为代表的现代生物理论越来越多的 进入了我们的视野. 如同大家所熟知的,基因是遗传因子,它记录了生命的基本构造和性能. 因此生物进化与基因的 ...

  7. JZOJ 100030. 【NOIP2017提高A组模拟7.8】为了爱情

    Description Input 输入文件第一行包含一个正整数 k.之后是 k 组测试用例. 每组测试用例的第一行为一个整数 n.接下来 n 行,每行 n 个以空格隔开的数,用来 描述棋盘的初始状态 ...

  8. JZOJ 5402. 【NOIP2017提高A组模拟10.8】God Knows

    Description Input Output Sample Input 5 3 1 4 5 2 3 4 3 4 1 Sample Output 5 Data Constraint Solution ...

  9. JZOJ 5405. 【NOIP2017提高A组模拟10.10】Permutation

    Description 你有一个长度为n 的排列P 与一个正整数K 你可以进行如下操作若干次使得排列的字典序尽量小 对于两个满足|i-j|>=K 且|Pi-Pj| = 1 的下标i 与j,交换P ...

最新文章

  1. jQuery 是为事件处理特别设计的。
  2. python 变量传值传引用 区分
  3. Java API帮助文档怎么查找?
  4. x3650m5不自动进系统_17日起,泉州这个地方自动抓拍系统启用!这些车闯红灯、严重超载、不按道行驶被查处曝光!【交通大整治】...
  5. 神策 FM | “微信之父”张小龙的四大关键产品原则
  6. c语言多进程架构改go语言,golang多进程并发
  7. 【ARM】异常产生指令
  8. acm java 类库_ACM java入门和基本技巧
  9. javaweb学习总结—jsp简单标签标签库开发
  10. opencv-api warpPerspective
  11. paip.c++ 转换 java 解决方案
  12. hive使用适用场景_ 如何将Hive与HBase整合联用
  13. ubuntu nsight使用
  14. Hibernate——缓存
  15. 2、CPP 基础语法学习
  16. 2021自学考试计算机应用基础,2021年高等教育自学考试计算机应用基础试题及答案.doc...
  17. java生成唯一的五位字符串_java唯一字符串ID生成方案详解
  18. jena mysql_在Jena框架下基于MySQL数据库实现本体的存取操作
  19. MATLAB字母识别
  20. 安装和配置zabbix-5.0.20

热门文章

  1. 如何转载CSDN的博客
  2. CUDA编程指南阅读笔记
  3. Linux服务器安装NodeJs简易方法
  4. 科大星云诗社动态20220114
  5. 八、“看夕阳西下,烂漫秋霞”
  6. 连表查询使用in_SQL 组合查询
  7. c#中一个简单的深拷贝方法
  8. js+Css实现的一个简单对话框
  9. 漫谈C++ Builder多线程编程技术
  10. 转移地址在内存中的jmp指令 检测点9.1