zoukankan      html  css  js  c++  java
  • 小P的团战

    20191005 T2

    原题链接

    By GKurumi

    题目描述:

    升级过技能的小P已经具备开团能力,他现在有N个技能,准备单挑对面的M个人

    但小P血非常少,所以他必须要控制住对面所有M个人,不然就会死掉

    已知第i种技能可以控制住Ki个人,分别为(a_{i1},a_{i2}……,a_{ik})

    问有多少种放技能的方式控住对面所有(M)个人(控制技能只能放一次,只有顺序不同的方式被认为是同一种)

    答案对1000000007取模

    输入格式:

    第一行两个整数(N)(M)

    接下来N行,每行第一个整数表示Ki,接Ki个整数表示(a_{i1},a_{i2}……,a_{ik})

    输出格式:

    一个整数表示放技能的方式数目

    样例

    样例输入
    4 5
    2 2 3
    2 1 2
    4 1 2 3 5
    4 1 2 4 5
    

    样例输出

    6
    

    题解:

    ​ 首先,我是我们机房最菜的人

    ​ 这道题乍一看有点像组合计数,但是我不会 太麻烦了推不出来,于是我就回想起那个月黑风高的夜晚发生的事统计方案用状压,于是就走上了一条不归路。

    ​ 思路:我们用一个数组存下每个技能能打到的位置,之后开始状压dp,dp的时候在用另一个数组存此时用技能打第i位上敌人的方案数。跑一遍下来之后,再遍历查找一遍位置,当i位上有方案的时候就加上方案数,无方案的时候就减去(因为我一开始算了一遍总的方案数(鬼知道我怎么想的)(可能太想跟计数原理扯上关系)我爱计数原理!!也可以直接计算方案数,看个人的喜欢。
    转移方程:if(i&(1<<j))f[i^(1<<j)]+=f[i],w[i]++;
    计算方案数:(ans+=(w[i]&1?-1:1)*ksm(2,f[i]))%=mod;

    以防出锅最后ans如果成了负数,emmm,就这么mod:(ans+mod)%mod

    考试时卑微的代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define mod 1000000007
    int f[1<<20],w[1<<20];
    int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch-'0');ch=getchar();}
    	return x*f;
    }
    int ksm(int a,int b)
    {
    	int ans=1;
    	while(b)
    	{
    		if(b&1)ans=(ans*a)%mod;
    		b>>=1;
    		a=(a*a)%mod;
    	}
    	return ans;
    }
    int n,m,x,k,sum,ans;
    signed main()
    {
    	freopen("carry.in","r",stdin);
    	freopen("carry.out","w",stdout);
    	n=read();m=read();
    	sum=(1<<m)-1;
    	for(int i=1;i<=n;i++)
    	{
    		k=read();
    		int w=0;
    		for(int j=1;j<=k;j++)
    		{
    			x=read();
    			w|=(1<<(x-1));
    		}
    		f[w^sum]++;
    	}
    	ans=ksm(2,n);
    	for(int j=0;j<m;j++)
    	{
    		for(int i=(1<<m)-1;i!=0;i--)
    		{
    			if(i&(1<<j))f[i^(1<<j)]+=f[i],w[i]++;
    		}
    	}
    	for(int i=1;i<(1<<m);i++)
    	{
    		(ans+=(w[i]&1?-1:1)*ksm(2,f[i]))%=mod;
    	}
    	cout<<(ans+mod)%mod;
    	return 0;
    }
    

    本人第一次写博客,请多见谅。

    如有转载,请标明出处,谢谢。

  • 相关阅读:
    笔记35 跨重定向请求传递数
    判断邮箱的正则表达式
    按钮
    async await 的用法
    笔记34 Spring MVC的高级技术——处理multipart形式的数据
    Convert Sorted Array to Binary Search Tree
    Binary Tree Zigzag Level Order Traversal
    Unique Binary Search Trees,Unique Binary Search Trees II
    Validate Binary Search Tree
    Populating Next Right Pointers in Each Node,Populating Next Right Pointers in Each Node II
  • 原文地址:https://www.cnblogs.com/GKurumi/p/11624879.html
Copyright © 2011-2022 走看看