Codeforces 451E Devu and Flowers(组合计数)

题目地址

在WFU(不是大学简称)第二次比赛中做到了这道题。高中阶段参加过数竞的同学手算这样的题简直不能更轻松,只是套一个容斥原理公式就可以。而其实这个过程放到编程语言中来实现也没有那么的复杂,不过为了让计算机在限定的时间内完成计算需要进行一些对计算上的优化。模MOD的情况下计算组合数nCr只需要求出分子再乘以分母的逆元,考虑到模的是1e9+7本身就是一个质数,根据费马小定理a^(MOD-2)即是a在模MOD意义下的逆元。求逆元的时候为了节约计算时间可以采用快速幂。计算过程就是容斥原理,就没有什么好说的了。

参考代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int MOD=(int)1e9+7;
 5 ll f[25],fact[25];
 6 ll fast_exp(ll base,ll exp,ll mod)
 7 {
 8     ll res=1;
 9     while(exp)
10     {
11         if(exp&1)
12             res=res*base%mod;
13         base=base*base%mod;
14         exp>>=1;
15     }
16     return res;
17 }
18 ll inverse_mod(ll x,ll mod)
19 {
20     return fast_exp(x,mod-2,mod);
21 }
22 ll nCr(ll n,ll r)
23 {
24     if(n<r)
25         return 0;
26     r=min(r,n-r);
27     ll ret=1;
28     for(ll x=n;x>n-r;x--)
29     {
30         ret=(ret*(x%MOD))%MOD;
31     }
32     ret=(ret*inverse_mod(fact[r],MOD))%MOD;
33     return ret;
34 }
35 int main()
36 {
37      ios_base::sync_with_stdio(false);
38      cin.tie(NULL);
39      int n,i,j,N,cnt;
40      ll s,temp,ans=0;
41      fact[0]=1;
42      for(i=1;i<25;i++)
43         fact[i]=(fact[i-1]*i)%MOD;
44      cin>>n>>s;
45      for(i=0;i<n;i++)
46         cin>>f[i];
47      N=1<<n;
48      for(i=0;i<N;i++)
49      {
50         temp=0,cnt=0;
51         for(j=0;j<n;j++)
52         {
53             if(i&(1<<j))
54             {
55                 temp+=(f[j]+1);cnt++;
56             }
57         }
58         if(temp>s)
59             continue;
60         ll x=nCr(s-temp+n-1,n-1);
61         if(cnt%2!=0)
62             x*=(-1);
63         ans=(ans+x+MOD)%MOD;
64      }
65      cout<<ans<<"\n";
66      return 0;
67 }

果然计算机和数学联系还是十分密切,当初搞数竞的时候觉得那些奇技淫巧恐怕难觅用武之地,结果现在才发现这些原来在编程中有很大的应用……眼前又是新的挑战,无论如何都不想再经历像高三那一年一样的绝望了吧……那么,加油吧,就像曾经一样,付出你的全部热情。不论你还相不相信你还可以成功,这都是可能使你回到巅峰的唯一途径了。让苦难成为力量。

时间: 2024-10-10 02:05:07

Codeforces 451E Devu and Flowers(组合计数)的相关文章

Codeforces 451E Devu and Flowers(容斥原理)

题目链接:Codeforces 451E Devu and Flowers 题目大意:有n个花坛.要选s支花,每一个花坛有f[i]支花.同一个花坛的花颜色同样,不同花坛的花颜色不同,问说能够有多少种组合. 解题思路:2n的状态,枚举说那些花坛的花取超过了,剩下的用C(n?1sum+n?1)隔板法计算个数.注意奇数的位置要用减的.偶数的位置用加的.容斥原理. #include <cstdio> #include <cstring> #include <cmath> #in

codeforces 451E Devu and Flowers

题意:有n个瓶子每个瓶子有 f[i] 支相同的颜色的花(不同瓶子颜色不同,相同瓶子花视为相同) 问要取出s支花有多少种不同方案. 思路: 如果每个瓶子的花有无穷多.那么这个问题可以转化为  s支花分到n个瓶子有多少种方案  用隔板法就能解决 C(s+n-1,n-1) .有限制之后我们可以 用 没限制的去减掉那些违反限制的 如果只有一个瓶子取得花超出上限 那么减去,两个瓶子 要加上(容斥原理) n只有20  就能暴力枚举那些取超过上限f[i]的瓶子并且在这些瓶子至少选出 f[i]+1 支花  统计

codeforces #451E Devu and Flowers 不定方程解的个数+lucas定理

题意:链接 方法:不定方程解的个数+lucas定理 解析: 感觉做了这么多不定方程解的个数之后,每一次就是改一次组合数求法- -! 这次mod的是质数,并且观察到n,m可能大于mod,所以lucas裸上.. 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 25 #define mod 1000000007 using nam

Codeforces Round #258 (Div. 2)Devu and Flowers 容斥原理

题目:Codeforces Round #258 (Div. 2)Devu and Flowers 题意:n个boxes ,第i个box有fi个flowers,每个boxes中的flowers完全相同,不同boxes的flowers不同,求从n个boxes中取出s个flowers的方案数.n<=20,s<=1e14,fi<=1e12. 排列组合的题目,一解法可用容斥原理(inclusion exclusion principle) . 有2中写法dfs和集合.下为集合写法. #inclu

Codeforces #258 Div.2 E Devu and Flowers

大致题意: 从n个盒子里面取出s多花,每个盒子里面的花都相同,并且每个盒子里面花的多数为f[i],求取法总数. 解题思路: 我们知道如果n个盒子里面花的数量无限,那么取法总数为:C(s+n-1, n-1) = C(s+n-1, s). 可以将问题抽象成:x1+x2+...+xn = s, 其中0<=xi <= f[i],求满足条件的解的个数. 两种方法可以解决这个问题: 方法一:这个问题的解可以等价于:mul = (1+x+x^2+...+x^f[1])*(1+x+x^2+...+x^f[2]

Yue Fei&#39;s Battle(组合计数递推)

//求一个直径为 k 的树有多少种形态,每个点的度不超过 3 // 非常完美的分析,学到了,就是要细细推,并且写的时候要细心 还有除法取模需要用逆元 #include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> using namespace std; #define MOD 1000000007 #define L

codeforces 439D Devu and Partitioning of the Array(有深度的模拟)

题目 //参考了网上的代码 注意答案可能超过32位 //要达成目标,就是要所有数列a的都比数列b的要小或者等于 //然后,要使最小的要和最大的一样大,就要移动(大-小)步, //要使较小的要和较大的一样大,也是要移动(较大-较小)步 //然后都加在一起就好了 #include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> using namespace std; #def

POJ 1496 POJ 1850 组合计数

Code Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 8256 Accepted: 3906 Description Transmitting and memorizing information is a task that requires different coding systems for the best use of the available space. A well known system is t

Codeforces 439E Devu and Birthday Celebration(计数问题)

题目链接:Codeforces 439E Devu and Birthday Celebration 题目大意:给出q,表示询问的次数,每次询问有n和f,问有多少种分类方法,将n分成f份,并且这f份的最大共约数为1. 解题思路:如果不考虑说最大共约数为1的话,那么问题很简单,就是f个数的和为n的种数C(f?1n?1).所以我们就尽量将问题转化成说f数的和为s的子问题.用容斥原理,总的可能减去公约数不为1的情况,那么公约数不为1的情况就去枚举公约数. #include <cstdio> #inc