zoukankan      html  css  js  c++  java
  • Jzoj5230 队伍统计

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

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

    发现数据很小,可以用状压dp

    我们设f[S][i]表示已经有i对矛盾关系,已经被选的集合为S的方案数

    那么显然转移可以用bitset预处理一下

    让后就可以卡过去

    #include<stdio.h>
    #include<time.h>
    #include<bitset>
    #define M 1000000007
    using namespace std;
    int f[1<<20][21],ans=0;
    int n,m,k;
    bitset<21> s[21],p;
    inline void add(int& x,int y){ x=(x+y)%M; }
    int main(){
    	freopen("count.in","r",stdin);
    	freopen("count.out","w",stdout);
    	scanf("%d%d%d",&n,&m,&k);
    	for(int x,y,i=0;i<m;++i){
    		scanf("%d%d",&x,&y);
    		s[--x][--y]=1;
    	}
    	f[0][0]=1;
    	for(int S=0;S<(1<<n);++S){
    		for(int i=0;i<=k;++i)
    		if(f[S][i]) 
    			for(int j=0;j<n;++j)
    				if(~S&(1<<j)){
    					p=S;
    					int t=(s[j]&p).count();
    					if(i+t<=k) add(f[S|(1<<j)][i+t],f[S][i]);
    				}
    	}
    	for(int i=0;i<=k;++i) add(ans,f[(1<<n)-1][i]);
    	printf("%d
    ",ans);
    }

  • 相关阅读:
    读《阿里云是如何失控的》有感
    LeetCode Search in Rotated Sorted Array 在旋转了的数组中查找
    界面编程模仿篇(QQ登录界面逼真篇)
    最牛B的编码套路
    QinQ封装及终结详解
    seaJs学习笔记之javascript的依赖问题
    Deploy maven on Linux OS
    c++——inline内联函数
    c++——引用
    c++——const关键字
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477207.html
Copyright © 2011-2022 走看看