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);
    }

  • 相关阅读:
    shell进行mysql统计
    java I/O总结
    Hbase源码分析:Hbase UI中Requests Per Second的具体含义
    ASP.NET Session State Overview
    What is an ISAPI Extension?
    innerxml and outerxml
    postman
    FileZilla文件下载的目录
    how to use webpart container in kentico
    Consider using EXISTS instead of IN
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477207.html
Copyright © 2011-2022 走看看