uva 11806 - Cheerleaders(容斥原理+二进制)

题目链接点击打开链接

题意:

n行m列网格放k个石子。有多少种方法?要求第一行,第一列,最后一行,最后一列必须有石子。

思路:

1.利用容斥原理的拓展

假设有三个集合 S 另有三个集合A B C,不属于 A、B、C任何一个集合,但属于全集S的元素, 奇数个减;偶数个加

此处是S为空集  A、B、C、D分别代表 行 列中的四种情况:

AUBUCUD = |A| + |B| + |C| + |D| - |AB| - |BC| - |AC| - |AD| - |BD| - |CD| + |ABC| + |ABD| + |ACD| + |BCD| - |ABCD|

如果在集合A或B中,相当于少了一行;如果在集合C或D中,相当于少了一列。

假定最后剩下row行、col列,方法数就是C(row*col,k)个

2.用二进制表示四种情况的搭配

3.计算组合数:C(n+1,k+1)=c(n,k+1)+(n,k)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long LL;
#define MOD 1000007
#define MAX 510
int c[MAX][MAX];
void C()//计算组合数
{
	memset(c,0,sizeof(c));
	c[0][0]=1;
	for(int i=0;i<=500;i++)
	{
		c[i][0]=c[i][i]=1;
		for(int j=1;j<i;j++)
		c[i][j]=(c[i-1][j]%MOD+c[i-1][j-1]%MOD)%MOD;
	}
}
int main()
{
  int T,ca=1;
  scanf("%d",&T);
  while(T--)
  {
  	C();
  	int m,n,K;
  	scanf("%d%d%d",&m,&n,&K);
  	int sum=0;
  	for(int i=0;i<16;i++)
  	{
  	  int count=0,row=m,col=n;
	  if(i&1)
	  {
	   row--;
	   count++;
	  }
	  if(i&2)
	  {
	   row--;
	   count++;
	  }
	  if(i&4)
	  {
	   col--;
	   count++;
	  }
	  if(i&8)
	  {
	   col--;
	   count++;
	  }
	  if(count&1)
	  sum=(sum+MOD-c[row*col][K])%MOD;//奇数个 减
	  else
	  sum=(sum+c[row*col][K])%MOD;//偶数个  加
	}
	printf("Case %d: %d\n",ca++,sum);
  }
  return 0;
} 

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 01:35:43

uva 11806 - Cheerleaders(容斥原理+二进制)的相关文章

uva 11806 - Cheerleaders(容斥原理)

题目链接:uva 11806 - Cheerleaders 题目大意:在一个m行n列的矩阵网里放k个石子,问有多少种画法?每个格子最多放一个石子,所有石子必须用完,并且在第一行.最后一行.第一列和最后一列都得有石子. 解题思路:容斥原理,我们可以先求说在m?n的矩阵上放k个石子的种数C(nmk),减掉四条边界不放的情况就是答案了.所以枚举16种状态,用二进制数表示说四条边中那些边是不放石子的. 代码 #include <cstdio> #include <cstring> cons

UVA 11806 - Cheerleaders(数论+容斥原理)

题目链接:11806 - Cheerleaders 题意:在一个棋盘上,要求四周的四行必须有旗子,问有几种摆法. 思路:直接算很容易乱掉,利用容斥原理,可知AUBUCUD = |A| + |B| + |C| + |D| - |AB| - |BC| - |AC| - |AD| - |BD| - |CD| + |ABC| + |ABD| + |ACD| + |BCD| - |ABCD| 由此利用位运算去计算即可 代码: #include <stdio.h> #include <string.

UVA - 11806 - Cheerleaders (递推)

UVA - 11806 Cheerleaders Time Limit: 2000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description C Cheerleaders In most professional sporting events, cheerleaders play a major role in entertaining the spectators. Their roles a

UVA - 11806 Cheerleaders (容斥原理)

题意:在N*M个方格中放K个点,要求第一行,第一列,最后一行,最后一列必须放,问有多少种方法. 分析: 1.集合A,B,C,D分别代表第一行,第一列,最后一行,最后一列放. 则这四行必须放=随便放C[N * M][K] - 至少有一行没放,即ABCD=随便放-A的补集 ∪ B的补集 ∪ C的补集 ∪ D的补集. 2.A的补集 ∪ B的补集 ∪ C的补集 ∪ D的补集,可用容斥原理计算,二进制枚举即可. #include<cstdio> #include<cstring> #incl

【递推】【组合数】【容斥原理】UVA - 11806 - Cheerleaders

http://www.cnblogs.com/khbcsu/p/4245943.html 本题如果直接枚举的话难度很大并且会无从下手.那么我们是否可以采取逆向思考的方法来解决问题呢?我们可以用总的情况把不符合要求的减掉就行了. 首先我们如果不考虑任何约束条件,我们可以得出如下结论:                                                                       下载我们假定第一行不站拉拉队员的所有的站立方法有A种.最后一行不站拉拉队员的

UVa 11806 Cheerleaders

题意:m行n列的矩形网格放k个相同的石子,要求第一行最后一行第一列最后一列都必须有石子,问有多少种放法 A为第一行没有石子的方案数,BCD依此类推,全集为S 如果没有任何要求的话,放法数应该是C(rc, k) 解法中利用容斥原理来解 所求的方案就是在S中但不在ABCD中任何一个的方案即:S - |A∪B∪C∪D| 而|A∪B∪C∪D| = |A| + |B| + |C| + |D| - |A∩B| - |A∩C| - |A∩D| - |B∩C| - |B∩D| - |C∩D| + |A∩B∩C|

uva 11806 Cheerleaders(容斥)

题意:如何摆放拉拉队的问题,在矩形网格m*n中,k名拉拉队员,要求四周网格中each side有至少一名拉拉队员,corner有人算两边,问有多少种摆法? 思路:容斥: c[m*n][k] -- c[(n-1)*m][k] U c[(n-1)*m][k] U c[n*(m-1)][k] U c[n*(m-1)][k] #include<cstdio> #include<iostream> #include<cstring> #define mod 1000007 usi

UVAL 11806 Cheerleaders 容斥原理

1.题意描述 本题大致意思是讲:给定一个广场,把它分为M行N列的正方形小框.现在给定有K个拉拉队员,每一个拉拉队员需要站在小框内进行表演.但是表演过程中有如下要求: (1)每一个小框只能站立一个拉拉队员: (2)广场的第一行,最后一行,第一列,最后一列都至少站有一个拉拉队员: (3)站在广场的四个角落的拉拉队员可以认为是同时占据了一行和一列. 2.思路: 本题如果直接枚举的话难度很大并且会无从下手.那么我们是否可以采取逆向思考的方法来解决问题呢?我们可以用总的情况把不符合要求的减掉就行了. 首先

UVA 1393 - Highways (容斥原理计数)

题目链接:1393 - Highways 题意:给定一个n * m的点阵,问两两相连后,能组成多少条至少穿过两个点的直线,并且不是水平或垂直的 思路:找过两点的线段,由于是整数坐标,只要他的斜率不是整数,即x / y不是整数就能满足答案,然后先记录下这所有的位置,然后利用容斥原理求出对应每个点可以连出多少条这样的线段,最后去求和,求和的时候要注意,由于有一些是重复计算了,比如1 1 和 2 2 连,2 2 和 3 3 连,这样其实是算一条的,所以最后在求和的时候要扣掉重复的部分,直接减去sum[