uva11806cheerleaders容斥原理,二进制

题意:给出m*n的网格,k个人,要求第一行,最后一行,第一列和最后一列必须有人。

思路:正难则反,考虑第一行,最后一行,第一列和最后一列都有人的要求都达不到的情况。sum=sum1-a-b-c-d+ab+ac+ad+bc+bd+cd-abc-abd-acd-bcd+abcd。sum1用0表示。a,b,c,d用1,2,4,8表示,用与运算,例:1&i若不为0则表示i含有a集合。例:11(1011)包含8,2,1,即d,b,a。

刘汝佳代码:

#include<iostream>
#include<cstring>
using namespace std;
const int MOD=1000007;
const int MAXK=500;
int C[MAXK+10][MAXK+10];
int main()
{
    memset(C,0,sizeof(C));
    C[0][0]=1;
    for(int i=0;i<=MAXK;i++)
    {
        C[i][0]=C[i][i]=1;
        for(int j=1;j<i;j++)
          C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
    }
    int T;
    scanf("%d",&T);
    for(int kase=1;kase<=T;kase++)
    {
        int n,m,k,sum=0;
        scanf("%d%d%d",&n,&m,&k);
        for(int s=0;s<16;s++)
        {
            int b=0,r=n,c=m;
            if(s&1){r--;b++;}
            if(s&2){r--;b++;}
            if(s&4){c--;b++;}
            if(s&8){c--;b++;}
            if(b&1)sum=(sum+MOD-C[r*c][k])%MOD;
            else sum=(sum+C[r*c][k])%MOD;
        }
        printf("Case %d:%d\n",kase,sum);
    }
    return 0;
}
时间: 2024-12-13 21:39:37

uva11806cheerleaders容斥原理,二进制的相关文章

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

题目链接 题意:在一个m*n的矩形网格里放k个相同的石子,问有多少种方法?每个格子最多放一个石子,所有石子都要放完,并且第一行.最后一行.第一列.最后一列都得有石子. 思路:假设满足第一行没有石子的方案集为A,最后一行没有石子的方案集为B,第一列没有石子的方案集为C,最后一列没有石子的方案集为D,全集为S,则所求答案就是"在S中但不在A,B,C,D任何一个集合中"的元素个数,这里就是运用容斥原理.程序中可以用二进制来表示集合. 代码: #include <iostream>

HDU 1796 How many integers can you find(容斥原理+二进制/dfs)

How many integers can you find Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5556    Accepted Submission(s): 1593 Problem Description Now you get a number N, and a M-integers set, you should

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| +

uva 11806 容斥原理+二进制

很容易想到要用容斥原理,这里有一个小技巧就是用二进制数来表示集合的交. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 typedef long long ll; 7 const int MOD = 1000007; 8 const int N = 501; 9 int cn[N][N]; 10 11 void init() 12 { 13

鸽巢原理和容斥原理

鸽巢原理又名抽屉原理 一种简单的表述法为: 若有n个笼子和n+1只鸽子,所有的鸽子都被关在鸽笼里,那么至少有一个笼子有至少2只鸽子. 另一种为: 若有n个笼子和kn+1只鸽子,所有的鸽子都被关在鸽笼里,那么至少有一个笼子有至少k+1只鸽子. 例子: 盒子里有10只黑袜子.12只蓝袜子,你需要拿一对同色的出来.假设你总共只能拿一次,只要3只就可以拿到相同颜色的袜子,因为颜色只有两种(鸽巢只有两个),而三只袜子(三只鸽子),从而得到“拿3只袜子出来,就能保证有一双同色”的结论. 有n个人(至少2人)

HDU 4336 集齐方便面卡片的期望-期望dp 或 容斥原理 -(二进制压缩辅助)

题意:要集齐n种卡片,现已知每打开一袋方便面得到每种卡片的概率Pi,Pi的和小于等于1,求集齐这n种卡片需要买的方便面的期望. 分析: 一.期望dp,这题要用二进制压缩,这是很显然的. 状态:dp[i]现在已经收集了i种卡片到达收集所有卡片的期望.这个状态能转移到的状态有:1).dp[i](下次打开的方便面得到的卡片是已经收集过的):2).dp[i|(1<<j)](下次得到的未收集过的卡片) 所以方程:dp[i]=Pi * dp[i] + Pj * dp[i|(1<<j)] + 1

POJ 3904 Sky Code (容斥原理)

题意:给定n个数,从n个数找出四个数,使这四个数的最大公约数为1,找出有多少对这样的组合. 找最大公约数不是1的有多少对. 题解:四个数的公约数为1,并不代表四个数两两互质.比如(2,3,4,5)公约数为1,但是 2和4并不互质.从反面考虑,先求出四个数公约数不为1的情况个数,用总的方案个数 减去四个数公约数不为1的情况个数就是所求. 求四个数公约数不为1的情况个数,需要将N个数每个数质因数分解,纪录下所有不同 的素因子所能组成的因子(就是4个数的公约数),并统计构成每种因子的素因子个数, 和因

UVA 10458 - Cricket Ranking(容斥原理)

UVA 10458 - Cricket Ranking 题目链接 题意:给定k个区间,要求用这些数字范围去组合成n,问有几种组合方式 思路:容斥原理,容斥是这样做:已知n个组成s,不限值个数的话,用隔板法求出情况为C(s + n - 1, n - 1),但是这部分包含了超过了,那么就利用二进制枚举出哪些是超过的,实现把s减去f(i) + 1这样就保证这个位置是超过的,减去这部分后,有多减的在加回来,这就满足了容斥原理的公式,个数为奇数的时候减去,偶数的时候加回 代码: #include <cst

UVa 11806 拉拉队(容斥原理)

https://vjudge.net/problem/UVA-11806 题意: 在一个m行n列的矩形网格里放k个相同的石子,有多少种方法?每个格子最多放一个石子,所有石子都要用完,并且第一行.最后一行.第一列.最后一列都得有石子. 思路: 如果考虑各种情况的话很复杂,设满足第一行没有石子的方案集为A,最后一行没有石子的方案集为B,第一列没有石子的方案集为C,最后一列没有石子的方案集为D,全集为S. 一个容斥原理的公式就可以解答出来,用二进制来枚举方案集的组合. 1 #include <iost