zoukankan      html  css  js  c++  java
  • 【NOIP2017模拟A组模拟8.5】队伍统计

    这题状压DP,设f[i][j]表示当前状态为i,有j个是违反了的方案数。
    转移嘛,就是

    f[i | (1<<k-1)][j+s]+=f[i][j]

    s表示如果k放在这儿的话会有多少个违反的

    上标:

    #include<cstdio>
    #define ll long long
    #define mo 1000000007
    using namespace std;
    struct node{int v,fr;}e[401];
    int n,m,K,M,tail[21],cnt=0;
    int ans=0,f[2097153][21],s=0;
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    void add(int u,int v) {e[++cnt]=(node){v,tail[u]}; tail[u]=cnt;}
    
    int main()
    {
    	freopen("count.in","r",stdin);
    	freopen("count.out","w",stdout);
    	n=read(),m=read(),K=read();
    	for (int i=1,u,v;i<=m;i++)
    		u=read(),v=read(),add(v,u);
    	f[0][0]=1;M=(1<<n)-1;
    	for (int i=0;i<=M;i++)
    		for (int j=0;j<=K;j++)
    		{
    			if (!f[i][j]) continue;
    			for (int k=1;k<=n;k++)
    			{
    				if (i & (1<<k-1)) continue;
    				s=0;
    				for (int p=tail[k];p;p=e[p].fr)
    					if (!(i & (1<<e[p].v-1))) s++;
    				if (j+s>K) continue;
    				(f[i|(1<<k-1)][j+s]+=f[i][j])%=mo;
    			}
    		}
    	for (int i=0;i<=K;i++) (ans+=f[M][i])%=mo;
    	printf("%d
    ",ans);
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    压缩与解压缩
    权限和特殊权限
    用户和组
    bash基础特性
    vim编辑器
    目录及文件操作命令
    ye
    软件包的安装与管理
    磁盘管理
    归档与展开归档
  • 原文地址:https://www.cnblogs.com/jz929/p/11817628.html
Copyright © 2011-2022 走看看