【NOIP2017模拟8.5】队伍统计

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),保证矛盾关系不重复。

n<=20,显然要状压DP,将排队的状态压成一个数来表示

对于一个队伍状态S,令F[S][k]表示S状态违反了k条矛盾的合法方案数,则有

F[S|2i-1][k+num(S&power[i])]=F[S|2i-1][k+num(S&power[i])]+F[S][k]

其中i表示某个不在队伍的人,num(i)表示i在二进制下1的个数,power[i]表示必须排在i后面的人的情况。

(实际操作中发现power[i]储存排在i后面的人的情况的时候运行速度远不及power[i]储存排在i前面的情况)

 1 #include<cstdio>
 2 using namespace std;
 3 const int qaq=1000000007;
 4 int f[1<<20][21],power[21],n,m,t;
 5 int main(){
 6     freopen("count.in","r",stdin);
 7     freopen("count.out","w",stdout);
 8     scanf("%d%d%d",&n,&m,&t);
 9     int u,v;
10     for (int i=1;i<=m;i++){
11         scanf("%d%d",&u,&v);
12         power[u]|=1<<(v-1);        //power[v]|=1<<(u-1);
13     }
14     f[0][0]=1;
15     for (int i=0;i<(1<<n);i++)
16      for (int j=0;j<=t;j++)
17          if (f[i][j])
18              for (int k=1;k<=n;k++)
19                  if ((i&(1<<(k-1)))==0){
20                      int qwq=power[k]&i;    //int qwq=power[k]^(power[k]&i);
21                      int sum=0;
22                                 while (qwq){
23                                  sum++;
24                                  qwq&=(qwq-1);
25                                 }
26                      if (j+sum<=t){
27                          f[i|(1<<(k-1))][j+sum]+=f[i][j];
28                      if (f[i|(1<<(k-1))][j+sum]>=qaq)
29                         f[i|(1<<(k-1))][j+sum]%=qaq;
30                     }
31                  }
32     int ans=0;
33     for (int i=0;i<=t;i++)
34      ans=(ans+f[(1<<n)-1][i])%qaq;
35     printf("%d\n",ans);
36     return 0;
37 }

神奇的代码

注意运算优先级,注意运算优先级,注意运算优先级!!!

时间: 2024-08-08 10:24:57

【NOIP2017模拟8.5】队伍统计的相关文章

【排序+模拟】vijos 1816 统计数字

标签:NOIP提高组2007 描述 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*10^9).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果. 格式 输入格式 第1行是整数n(1<=n<=200000),表示自然数的个数. 第2~n+1行每行一个自然数. 输出格式 输出包含m行(m为n个自然数中不相同数的个数),按照自然数从小到大的顺序输出.每行输出两个整数,分别是自然数和该数出现的次数,其间用一个空

jzoj 5230_队伍统计_dp

题目描述 现在有n个人要排成一列,编号为1->n .但由于一些不明原因的关系,人与人之间可能存在一些矛盾关系,具体有m条矛盾关系(u,v),表示编号为u的人想要排在编号为v的人前面.要使得队伍和谐,最多不能违背k条矛盾关系(即不能有超过k条矛盾关系(u,v),满足最后v排在了u前面).问有多少合法的排列.答案对10^9+7取模. 思路 看到数据范围就应该可以想到可以用状压dp,我们用f[i][j]表示第i终状态违背了j次的排列数量,i这个状态在二进制中表示每一位有没有被选到 我们先考虑转移,我们

JZOJ.5281【NOIP2017模拟8.15】钦点

Description Input Output Sample Input 4 4 2 a a b b a a b b c c d d c c d d 1 1 3 3 2 2 3 1 1 3 2 2 Sample Output d d c c  d d c c  b b a a  b b a a  Data Constraint 本题时限4s. 很明显这是一道模拟题,朴素算法O(nmq)看似过得去,实际上字符串的操作是很慢的,同样对字符串赋值10w次比对数组元素赋值10w次要慢3倍以上. 实际上

暑假第二次考试 冲刺Noip2017模拟赛2 解题报告——五十岚芒果酱

题1 牛跑步(running) [题目描述] 新牛到部队,CG 要求它们每天早上搞晨跑,从 A 农场跑到 B 农场.从 A 农场到 B 农场中有 n-2 个路口,分别标上号,A 农场为 1 号,B 农场为 n 号,路口分别为 2...n-1 号,从 A 农场到 B 农场有很多条路径可以到达,而 CG 发现有的路口是必须经过的,即每条路径都经过的路口,CG 要把它们记录下来,这样 CG 就可以先到那个路口,观察新牛们有没有偷懒,而你的任务就是找出所有必经路口. [输入格式] 第一行两个用空格隔开的

冲刺Noip2017模拟赛8 解题报告——五十岚芒果酱

1.鼎纹 [问题描述] 据说鼎纹的 种制造 式是 铜模印出来的,这是我国古代劳动 智慧 的结晶.铜模印过的地 ,会留下深深的印记,经过时间的炼化,洗 练成历史的遗存. 聪明的古代劳动人民拥有一个 a 行 b 列的铜模,每个位置要么是 0(代表 这个点是平的),要么是 1(代表这个点是凸起的).他们想造 个 n 行 m 列 的鼎 ,其中每个位置也都是 0 或 1,表示经过若干 次印后,每个位置的结果. 有一些要求.铜模是不能旋转和翻转的:在印的过程当中,铜模的凸起不 能出现在鼎面的外面(平的部分是

JZOJ.5305【NOIP2017模拟8.18】C

Description Input Output Sample Input 10 11 1 2 2 3 3 4 1 4 3 5 5 6 8 6 8 7 7 6 7 9 9 10  6 1 2 3 5 6 9 9 2 9 3 9 10  Sample Output 2 2 2 4 4 1  Data Constraint Hint 题意有点问题,实际上简单路径这里指的是不经过重复边的路径. 这题Tarjan缩点,然后LCA统计两点间环的个数k,答案就是2k个路径. 1 #include<iostr

JZOJ.5307【NOIP2017模拟8.18】偷窃

Description Input Output Sample Input 5 5 1 4 0 5 2 2 1 2 0 1 0 2 3 4 4 0 3 0 3 1 1 2 2 1 1 Sample Output 9 Data Constraint Hint 本题直接做比较麻烦,加上金砖可移动. 这题就是要求我们找出一种摆放方式,三视图与之前一样且用得金块数最少. 我们可以重新构造. 对于俯视图,它提供的信息就是我们要在哪里放金砖,哪里不能放金砖. 对于正视图和侧视图,它提供的信息就是某一行或某一

JZOJ.5264【NOIP2017模拟8.12】化学

Description Input Output Sample Input 3 10 1 2 10 Sample Output 5 Data Constraint Hint 搜索.考虑到m很大,我们不得不从n下手,但240无法满足要求,我们可以采取折半搜索. 先搜前20个记录所有220的方案情况,再搜索后面20个,把全部方案数分别记录到两个数组里,从小到大排个序,然后用指针维护统计答案就可以了. 因为要两个情况所耗费的体力值不大于m,所以我们可以固定第一个数组的指针i,第二个数组指针j从大到小找

冲刺Noip2017模拟赛7 解题报告——五十岚芒果酱

1.二叉树(binary) 1.二叉树 (binary.cpp/c/pas) [问题描述] 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值: (3)左.右子树也分别为二叉排序树: (4)没有键值相等的结点. 完全二叉树:只有最下面的两层结点度能够小于2,并且最下面一层的结点 都集中在该层最左边的若干位置的二叉树. 图1中,(a)和(b)是完全二叉树,(c)和(