自己写的代码:

#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. <Linux系统hostname命令详解>

    hostname命令的用法的小知识我们都知道hostname命令是查看主机名和修改主机名的. [root@apache ~]# hostname  //查看本机的主机名apache.example.c ...

  2. javascript代码复用--继承

    由于javascript没有类的概念,因此无法通过接口继承,只能通过实现继承.实现继承是继承实际的方法,javascript中主要是依靠原型链要实现. 原型链继承 原型链继承是基本的继承模式,其本质是 ...

  3. linux服务器修改ssh默认22端口方法

    1.登录服务器,打开sshd_config文件 # vim /etc/ssh/sshd_config 2.找到#Port 22,默认是注释掉的,先把前面的#号去掉,再插入一行设置成你想要的端口号,注意 ...

  4. python_day2_homework_1(简单购物商城)

    '''简单购物商城(要求):1,商品展示,价格2,买,加入购物车3,付款,钱不够''' 1 #_*_ coding: utf-8 _*_ __author__ = 'A-rno' meu_list_1 ...

  5. openerp学习笔记 domain 增加扩展支持,例如支持 <field name="domain">[('type','=','get_user_ht_type()')]</field>

    示例代码1,ir_action_window.read : # -*- coding: utf-8 -*-from openerp.osv import fields,osv class res_us ...

  6. javascript和jquery 获取触发事件的元素

    一个很简单的问题,却因为大意,经常忘了处理,导致程序运行出错. <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  7. zendframework 事件管理(一)

    zend里的事件管理器主要是为了实现: 1.观察者模式 2.面向切面设计 3.事件驱动构架 事件管理最基本的功能是将监听器与事件连接或断开.不论时连接还是断开都是通过shared collection ...

  8. js 前加分号和感叹号是什么意思?

    ;!function(){}();  ;!有什么用? 从语法上来开,Javascript中分号表示语句结束,在开头加上,可能是为了压缩的时候和别的方法分割一下,表示一个新的语句开始.所以,如果在一个单 ...

  9. mysql 连接语句

    在 SELECT 语句中,如果 FROM 子句引用了多个表源或视图,可以使用 JOIN 指示指定的联接操作应在指定的表源或视图之间执行. 一.交叉联接:CROSS JOIN 交叉联接将执行一个叉积(迪 ...

  10. Session设置不当导致API变成单线程问题的解决

    起因: 最近开发一个项目,有个接口很慢(数据库的问题),然后在执行期间,随手去点了其他功能(调用其他接口),发现不响应了.等那个很慢的接口返回结果了,这个功能才立马返回结果.  这明显是一个问题啊! ...