自己写的代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
/*
题意:相当于在一个m*n的矩形网格里放k个相同的石子,问有多少种方法?
限制条件:每个格子最多放一个石子,所有石子都要用完,并且第一行、最后一行、第一列、最后一列都得有石子。
思路:
直接求的话会比较麻烦,反过来想:
设总方案数为S,A={第一行没有石子},B={最后一行没有石子},C={第一列没有石子},D={最后一列没有石子}
利用容斥原理,先求|A并B并C并D|,然后再用|s|-|A并B并C并D|,即为答案。
而对于有r行,t列,摆放k个石子的方案数为C(r*t,k)。
*/
using namespace std;
const int maxn=;
const int mod=;
long long c[maxn*maxn][maxn*maxn];
int t,m,n,k;
void init(){
memset(c,,sizeof(c)); //先初始化为0,因为在计算容斥原理的时候,很有可能会出现C(i,j)(j>i)的情形,此时应该值为0
c[][]=;
for(int i=;i<maxn*maxn;i++){ //求出组合数
c[i][]=;
for(int j=;j<i;j++)
c[i][j]=(c[i-][j-]+c[i-][j])%mod;
c[i][i]=;
}
}
int main()
{
long long ans,tmp;
init();
scanf("%d",&t);
for(int i=;i<=t;i++){
ans=;
scanf("%d%d%d",&m,&n,&k);
if(k>m*n||k<)
ans=;
else{
//先求|A并B并C并D|,由于只有四个元素,所以直接写出式子了
ans=(*c[(m-)*n][k]+*c[m*(n-)][k])%mod;
tmp=((c[(m-)*n][k]+*c[(m-)*(n-)][k]%mod)%mod+c[(n-)*m][k])%mod;
ans=(ans-tmp+mod)%mod;
ans=(ans+*c[(m-)*(n-)][k])%mod;
ans=(ans+*c[(m-)*(n-)][k])%mod;
ans=(ans+mod-c[(m-)*(n-)][k])%mod; ans=(c[m*n][k]-ans+mod)%mod; //最后再用所有总的方案数减去ans值,即为最后要求的答案
}
printf("Case %d: %lld\n",i,ans);
}
return ;
}

白书上的代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
/*
题意:相当于在一个m*n的矩形网格里放k个相同的石子,问有多少种方法?
限制条件:每个格子最多放一个石子,所有石子都要用完,并且第一行、最后一行、第一列、最后一列都得有石子。
思路:
直接求的话会比较麻烦,反过来想:
设总方案数为S,A={第一行没有石子},B={最后一行没有石子},C={第一列没有石子},D={最后一列没有石子}
利用容斥原理,先求|A并B并C并D|,然后再用|s|-|A并B并C并D|,即为答案。
而对于有r行,t列,摆放k个石子的方案数为C(r*t,k)。
*/
using namespace std;
const int maxn=;
const int mod=;
int C[maxn*maxn][maxn*maxn];
int t,m,n,k;
void init(){
memset(C,,sizeof(C)); //先初始化为0,因为在计算容斥原理的时候,很有可能会出现C(i,j)(j>i)的情形,此时应该值为0
C[][]=;
for(int i=;i<maxn*maxn;i++){ //求出组合数
C[i][]=;
for(int j=;j<i;j++)
C[i][j]=(C[i-][j-]+C[i-][j])%mod;
C[i][i]=;
}
} int main()
{
init();
scanf("%d",&t);
for(int i=;i<=t;i++){
int sum=;
scanf("%d%d%d",&m,&n,&k);
//枚举所有16种搭配方式,s=0表明是总的方案数
//由于最后我们求的是补给的个数,所以在用容斥原理的时候稍作修改:
//原本奇数个集合是加,改为减;偶数个集合是减,改为加
for(int s=;s<;s++){
int b=,r=n,c=m; //b统计该方案数对应的集合的个数,r和c是可以放置的行列数
if(s&){
b++;
r--;
}
if(s&(<<)){
b++;
r--;
}
if(s&(<<)){
b++;
c--;
}
if(s&(<<)){
b++;
c--;
}
if(b&)
sum=(sum+mod-C[r*c][k])%mod; //奇数个集合,做减法
else
sum=(sum+C[r*c][k])%mod; //偶数个集合,做加法
}
printf("Case %d: %d\n",i,sum);
}
return ;
}

UVA 11806 Cheerleaders (组合+容斥原理)的更多相关文章

  1. UVA.11806 Cheerleaders (组合数学 容斥原理 二进制枚举)

    UVA.11806 Cheerleaders (组合数学 容斥原理 二进制枚举) 题意分析 给出n*m的矩形格子,给出k个点,每个格子里面可以放一个点.现在要求格子的最外围一圈的每行每列,至少要放一个 ...

  2. UVa 11806 - Cheerleaders (组合计数+容斥原理)

    <训练指南>p.108 #include <cstdio> #include <cstring> #include <cstdlib> using na ...

  3. UVa 11806 Cheerleaders (容斥原理+二进制表示状态)

    In most professional sporting events, cheerleaders play a major role in entertaining the spectators. ...

  4. UVA 11806 Cheerleaders (容斥原理

    1.题意描述 本题大致意思是讲:给定一个广场,把它分为M行N列的正方形小框.现在给定有K个拉拉队员,每一个拉拉队员需要站在小框内进行表演.但是表演过程中有如下要求: (1)每一个小框只能站立一个拉拉队 ...

  5. UVa 11806 Cheerleaders (数论容斥原理)

    题意:给定一个n*m的棋盘,要放k个石子,要求第一行,最后一行,第一列,最后一列都有石子,问有多少种放法. 析:容斥原理,集合A是第一行没有石子,集合B是最后一行没有石子,集合C是第一列没有石子,集合 ...

  6. UVA - 11806 Cheerleaders (容斥原理)

    题意:在N*M个方格中放K个点,要求第一行,第一列,最后一行,最后一列必须放,问有多少种方法. 分析: 1.集合A,B,C,D分别代表第一行,第一列,最后一行,最后一列放. 则这四行必须放=随便放C[ ...

  7. uva 11806 Cheerleaders

    // uva 11806 Cheerleaders // // 题目大意: // // 给你n * m的矩形格子,要求放k个相同的石子,使得矩形的第一行 // 第一列,最后一行,最后一列都必须有石子. ...

  8. UVA 11806 Cheerleaders (容斥原理)

    题意 一个n*m的区域内,放k个啦啦队员,第一行,最后一行,第一列,最后一列一定要放,一共有多少种方法. 思路 设A1表示第一行放,A2表示最后一行放,A3表示第一列放,A4表示最后一列放,则要求|A ...

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

    http://www.cnblogs.com/khbcsu/p/4245943.html 本题如果直接枚举的话难度很大并且会无从下手.那么我们是否可以采取逆向思考的方法来解决问题呢?我们可以用总的情况 ...

随机推荐

  1. AutoEventWireup="false"

    在 Web 服务器控件中,某些事件(通常是 Click 事件)会导致窗体被回发到服务器.HTML 服务器控件和 Web 服务器控件(如 TextBox 控件)中的更改事件将被捕获,但不会立即导致发送. ...

  2. linux编程:环境表

    每个进程在启动的时候都会收到一张环境表.环境表是由一个字符指针数组组成,每个指针包含一个以NULL结束的字符串的地址,全局变量environ包含了指针数组的地址: extern char **envi ...

  3. visifire3.6.8 去水印方法

    visifire 很NB的一套开源图表 不多介绍 详询google 3.0以下版本可以直接继承Chart类 override 加水印的函数就可以, 3.0以上版本需要自己编译源代码 这个水印函数藏得有 ...

  4. 一路走过的2013,welcome to 2014

    驻入博客园,还是在大学时,至今没写过一篇博客,一直都是在看人家写的博客.2014 年第一天,就从这一天,开启博客之旅,与大家分享好书,分享技术,结交好朋友. 简单,介绍下自己,大三实习,因为热衷于互联 ...

  5. Eclipse导入android包错误

    错误提示:Invalid project description… 解决方案:假设你的工作空间是workshop,那么你可以在你的workshop下新建一个文件夹,然后放入你的包,再在Eclipse中 ...

  6. How to add EDT relation table[AX2012]

    setp 1. First create New Edit. setp 2.Create New Table First Table Name is NParentRel then drag and ...

  7. highchars

    var drawChart = function(sourceUrl) { $.ajax({ "type" : "post", "url" ...

  8. nginx demo

    server_names_hash_bucket_size 512;upstream node_app { server 127.0.0.1:3000; } server { listen 80; s ...

  9. GDAL编译(转)

    一.简单的编译 1.使用VisualStudio IDE编译 首先进入GDAL的源代码目录,可以看到有几个sln为后缀的文件名,比如makegdal10.sln,makegdal80.sln,make ...

  10. error:LNK2005 已经在*.obj中定义

    为什么会出现这个错误??“error LNK2005: 已经在*.obj中定义”  编程中经常能遇到LNK2005错误——重复定义错误,其实LNK2005错误并不是一个很难解决的错误,弄清楚它形成的原 ...