题目

原题目

点这里

简易题意

包裹里有无限个分布均匀且刚好 \(c\) 种颜色的巧克力,现在要依次拿 \(n\) 个出来放到桌子上。每次如果桌子上面有两种相同颜色的巧克力就会把这两个巧克力给吃掉,求最后桌子上面还有 \(m\) 个巧克力的概率。


思路分析

首先,我们考虑使用概率 \(\text{DP}\) ,似乎是可做的。

但是,由于本题数据范围限制:\(N,M\le 1000000\) ,如果再从 \(DP\) 的角度思考,时间复杂度似乎有些出乎所料了,考虑用其他办法解决此题。

本人经验之谈:

没有入手点——考虑分析题目特性,进而找到对应方法解决此题。

考虑本题的一些特性:

  • \(m\le c\) ,因为如果糖果超出了 \(c\) ,就必定有重复的颜色出现,就被吃掉了。
  • \(m\le n\) ,显然吧...
  • \(2\mid (n-m)\) ,因为被吃掉当有两块重复的巧克力。
  • 设颜色 \(i\) 的糖果被取出来的次数为 \(t_i\) 。那么,如果 \(2\mid t_i\) ,则颜色 \(i\) 最终不会生下来;反之,颜色 \(i\) 最终会剩下来。
  • 方案数共 \(c^n\) 种,显然...

考虑从这些特性入手。

对于前三个特征,似乎只是我们的骗分策略...当然,对于特征一,可以用来优化 \(DP\) ,但是还需卡常才能过。

针对特征四,似乎可以进行发散:

对于我们取出来的 \(n\) 个球,有 \(m\) 个颜色取了奇数个,剩余 \(c-m\) 个颜色取了偶数个。

有过生成函数的经验,我们似乎可以很容易列出生成函数。

对于奇数颜色

\[F(x)=\sum_{i=0}^\infty x^{2i+1}
\]

对于偶数颜色

\[G(x)=\sum_{i=0}^\infty x^{2i}
\]

如果我们按通常的方法,将他们卷起来,你就会发现,即使你 \(WA\) 穿了,这道题也做不对。

为什么?因为这道题求的是概率,但如果你就这样卷起来,其顺序是不对的。

举个栗子,取颜色的顺序为 \(112\) 与颜色顺序 \(121\) 。

这两种剩下的结果都是 \(2\) ,但是它们属于不同的方案。

我们就要先想办法将他们变成相同的方案,最后再乘以其排列 \(n!\) 。

引入指数型母函数的性质:

指数型母函数的标志函数一般为 \(\frac{x^0}{0!}+\frac{x^1}{1}+\frac{x^2}{2!}+...\) ,对于 \(\frac{x^i}{i!}\) 表示在一个方案中某个元素出现了 \(i\) 次,而不同位置的该种元素本质不同,所以在记方案数时只算作一种,所以最后结果应处以 \(i!\) 。

根据指数型母函数的定义,对于奇数的颜色,其生成函数应该为

\[F(x)=\frac{x}{1!}+\frac{x^3}{3!}+\frac{x^5}{5!}+\ldots\ldots=\sum_{i=0}^{\infty}\frac{x^{2i+1}}{(2i+1)!}
\]

同理,偶数的颜色为

\[G(x)=1+\frac{x^2}{2!}+\frac{x^4}{4!}+\ldots\ldots=\sum_{i=0}^{\infty}\frac{x^{2i}}{(2i)!}
\]

那么,答案的生成函数即为

\[H(x)=F^m(x)\cdot G^{c-m}(x)
\]

注:从此处开始,我们就开始一直处理其系数问题,而最后的排列需要在此基础上乘以 \(n!\) 。

考虑如何化简 \(H(x)\) ,想办法简化 \(F、G\) 。

分析其一般形式,令 \(A(x)=\sum_{i=0}^\infty \frac{x^i}{i!}\) 。

有 \(e^x=A(x)\) ,下面进行证明:

设 \(B(x)=e^x\) ,已知 \(e\) 的特性:

\(f(x)=e^x\) 存在任意阶导数,且 \(f^{(n)}(x)=f(x)\) 。

那么,我们考虑将 \(B(x)\) 在 \(x_0=0\) 处进行泰勒展开,那么就有

\[\begin{aligned}
B(x)&=B(0)+\frac{B'(0)}{1!}(x-0)^1+\frac{B''(0)}{2!}(x-0)^2+\frac{B'''(0)}{3!}(x-0)^3+\ldots\ldots \\
&=1+\frac{1}{1}x+\frac{1}{2!}x^2+\frac{1}{3!}x^3+\ldots\ldots \\
&=\sum_{i=0}^\infty \frac{x^i}{i!} \\
&=A(x)
\end{aligned}
\]

所以,就有 $ek=\sum_{i=0}\infty \frac{x^i}{i!} $

那么,\(e^{-k}=\sum_{i=0}^\infty \frac{x^i}{i!}(-1)^i\)

有了这个工具,我们就可以很好地表示 \(F、G\) ,显然

\[\left\{
\begin{aligned}
F(x)&=\frac{e^k-e^{-k}}{2} \\
G(x)&=\frac{e^k+e^{-k}}{2}
\end{aligned}
\right.
\]

那么就有

\[\begin{align}
H(x)&=F^m(x)G^{c-m}(x) \\
&=(\frac{e^x-e^{-x}}{2})^m\times(\frac{e^x+e^{-x}}{2})^{c-m}\tag{1} \\
&=\frac{\sum\limits_{k=0}^{m}(-1)^kC_{m}^{k}e^{(m-k)x}e^{-kx}}{2^m}\times \frac{\sum\limits_{k=0}^{c-m}C_{c-m}^{k}e^{(c-m-k)x}e^{-kx}}{2^{c-m}}\tag{2} \\
&=2^{-c}\times \sum_{i=0}^{m}(-1)^i{m\choose i}\times e^{(m-2i)x}\times \sum_{j=0}^{c-m}{c-m\choose j}\times e^{(2j-c+m)x} \\
&=2^{(-c)}\times \sum_{i=0}^{m}\sum_{j=0}^{c-m}(-1)^i{m\choose i}{c-m\choose j}\times e^{(2m-2i+2j-c)x}\\
&=2^{(-c)}\times \sum_{i=0}^{m}\sum_{j=0}^{c-m}(-1)^i{m\choose i}{c-m\choose j}\times \sum_{k=0}^{\infty}\frac{((2m-2i+2j-c)x)^k}{k!}
\end{align}
\]

其中,我们将 \((1)\) 二项式展开之后得到 \((2)\) ,然后再将其化简得到后面的算式。

出现了 \(x^k\) ,我们将它换个写法:

\[H(x)=\sum_{k=0}^\infty \frac{\sum_{i=0}^{m}\sum_{j=0}^{c-m}(-1)^i{m\choose i}{c-m\choose j}\times (2m-2i+2j-c)^k}{2^ck!}x^k
\]

那么,\(x^n\) 的系数 \(a_n\) 的值就是

\[a_n=\frac{\sum_{i=0}^{m}\sum_{j=0}^{c-m}(-1)^i{m\choose i}{c-m\choose j}\times (2m-2i+2j-c)^n}{2^cn!}
\]

由于我们处理的是系数,那么答案就是

\[\frac{a_n\times C_c^m \times n!}{c^n}
\]

而 \(a_n\) 中有一个 \(\frac{1}{n!}\) ,所以我们将 \(a_n\) 分母中的 \(n!\) 去掉,答案就变为

\[\frac{a_n'\times C_c^m}{c^n}
\]

其中

\[a_n'=a_n\times n!=\frac{\sum_{i=0}^{m}\sum_{j=0}^{c-m}(-1)^i{m\choose i}{c-m\choose j}\times (2m-2i+2j-c)^n}{2^c}
\]

代码

#define rep(i,__l,__r) for(int i=__l,i##_end_=__r;i<=i##_end_;++i)
#define fep(i,__l,__r) for(int i=__l,i##_end_=__r;i>=i##_end_;--i) const int MAXN=100; inline double qkpow(double a,int n){
// printf("Now qkpow : a == %.3lf, n == %d\n",a,n);
double ret=1;
for(;n>0;n>>=1){
if(n&1)ret*=a;
a*=a;
// printf("Now n == %d, a == %.3lf, ret == %.3lf\n",n,a,ret);
}
// printf("ans == %.3lf\n",ret);
return ret;
} double C[MAXN+5][MAXN+5]; inline void init(){
C[0][0]=1;
rep(i,1,MAXN){
C[i][0]=1;
rep(j,1,i){
C[i][j]=C[i-1][j-1]+C[i-1][j];
}
}
} signed main(){
#ifdef FILEOI
freopen("file.in","r",stdin);
freopen("file.out","w",stdout);
#endif
int c,n,m;
double a;
init();
while(c=qread()){
qread(n,m);a=0;
if(m>c || m>n || (n-m)&1){
puts("0.000");
continue;
}
rep(i,0,m)rep(j,0,c-m){
a+=(i&1?-1:1)*C[m][i]*C[c-m][j]*qkpow((2*m-2*i+2*j-c)*1.0/c,n);
//此处的快速幂的底数 /c 的原因是为了防止爆 double , 而我们本来就要除以 c^n , 因而我们就在 qkpow 里面处理掉了
}
a=a*C[c][m]/qkpow(2.0,c);
printf("%.3lf\n",a);
}
return 0;
}

练习题

\(\text{[HDU2056]}\) "红色病毒"问题

#include<cstdio>
#include<vector>
#include<utility>
#include<algorithm>
using namespace std; #define rep(i,__l,__r) for(int i=__l,i##_end_=__r;i<=i##_end_;++i)
#define fep(i,__l,__r) for(int i=__l,i##_end_=__r;i>=i##_end_;--i)
#define writc(a,b) fwrit(a),putchar(b)
#define mp(a,b) make_pair(a,b)
#define ft first
#define sd second
#define LL long long
#define ull unsigned long long
#define uint unsigned int
#define pii pair<int,int>
#define Endl putchar('\n')
// #define FILEOI
// #define int long long #ifdef FILEOI
#define MAXBUFFERSIZE 500000
inline char fgetc(){
static char buf[MAXBUFFERSIZE+5],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXBUFFERSIZE,stdin),p1==p2)?EOF:*p1++;
}
#undef MAXBUFFERSIZE
#define cg (c=fgetc())
#else
#define cg (c=getchar())
#endif
template<class T>inline void qread(T& x){
char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
if(f)x=-x;
}
inline int qread(){
int x=0;char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
return f?-x:x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
inline int gcd(const int a,const int b){return b?gcd(b,a%b):a;}
inline void getInv(int inv[],const int lim,const int MOD){
inv[0]=inv[1]=1;for(int i=2;i<=lim;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
}
template<class T>void fwrit(const T x){
if(x<0)return (void)(putchar('-'),fwrit(-x));
if(x>9)fwrit(x/10);putchar(x%10^48);
}
inline LL mulMod(const LL a,const LL b,const LL mod){//long long multiplie_mod
return ((a*b-(LL)((long double)a/mod*b+1e-8)*mod)%mod+mod)%mod;
} const int MOD=100; ull N;int T; inline int qkpow(int a,ull n){
int ret=1;
for(;n>0;n>>=1,(a*=a)%=MOD)if(n&1)(ret*=a)%=MOD;
return ret;
} signed main(){
#ifdef FILEOI
freopen("file.in","r",stdin);
freopen("file.out","w",stdout);
#endif
int cas;
while((T=qread())^(cas=0)){
while(T--){
qread(N);
printf("Case %d: ",++cas);
writc((qkpow(4,N-1)+qkpow(2,N-1))%MOD,'\n');
}
Endl;
}
return 0;
}

「题解」「POJ1322」Chocolate的更多相关文章

  1. 「ZJOI2019」&「十二省联考 2019」题解索引

    「ZJOI2019」&「十二省联考 2019」题解索引 「ZJOI2019」 「ZJOI2019」线段树 「ZJOI2019」Minimax 搜索 「十二省联考 2019」 「十二省联考 20 ...

  2. 「题解」「美团 CodeM 资格赛」跳格子

    目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...

  3. 「题解」「HNOI2013」切糕

    文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...

  4. 「题解」JOIOI 王国

    「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...

  5. 【题解】「P6832」[Cnoi2020]子弦

    [题解]「P6832」[Cnoi2020]子弦第一次写月赛题解( 首先第一眼看到这题,怎么感觉要用 \(\texttt{SAM}\) 什么高科技的?结果一仔细读题,简单模拟即可. 我们不难想出,出现最 ...

  6. 「题解报告」 P3167 [CQOI2014]通配符匹配

    「题解报告」 P3167 [CQOI2014]通配符匹配 思路 *和?显然无法直接匹配,但是可以发现「通配符个数不超过 \(10\) 」,那么我们可以考虑分段匹配. 我们首先把原字符串分成多个以一个通 ...

  7. 「bzoj1003」「ZJOI2006」物流运输 最短路+区间dp

    「bzoj1003」「ZJOI2006」物流运输---------------------------------------------------------------------------- ...

  8. 「bzoj1925」「Sdoi2010」地精部落 (计数型dp)

    「bzoj1925」「Sdoi2010」地精部落---------------------------------------------------------------------------- ...

  9. 「BZOJ1924」「SDOI2010」 所驼门王的宝藏 tarjan + dp(DAG 最长路)

    「BZOJ1924」[SDOI2010] 所驼门王的宝藏 tarjan + dp(DAG 最长路) -------------------------------------------------- ...

  10. 「LOJ#10051」「一本通 2.3 例 3」Nikitosh 和异或(Trie

    题目描述 原题来自:CODECHEF September Challenge 2015 REBXOR 1​​≤r​1​​<l​2​​≤r​2​​≤N,x⨁yx\bigoplus yx⨁y 表示 ...

随机推荐

  1. mysql(5):主从复制和分库分表

    主从复制集群 概念:主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点. 使用场景: 读写分离:使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读 ...

  2. 安装符合rancher2.x要求的docker

    安装符合rancher2.x要求的docker 待办 https://rancher.com/docs/rancher/v2.x/en/installation/requirements/instal ...

  3. leetcode 64. 最小路径和 动态规划系列

    目录 1. leetcode 64. 最小路径和 1.1. 暴力 1.2. 二维动态规划 2. 完整代码及执行结果 2.1. 执行结果 1. leetcode 64. 最小路径和 给定一个包含非负整数 ...

  4. 题解【洛谷P2615】[NOIP2015]神奇的幻方

    题目描述 幻方是一种很神奇的 \(N \times N\) 矩阵:它由数字 \(1,2,3,\cdots \cdots ,N \times N\) 构成,且每行.每列及两条对角线上的数字之和都相同. ...

  5. 【Python】【爬虫】爬取酷狗TOP500

    好啦好啦,那我们来拉开我们的爬虫之旅吧~~~ 这一只小爬虫是爬取酷狗TOP500的,使用的爬取手法简单粗暴,目的是帮大家初步窥探爬虫长啥样,后期会慢慢变得健壮起来的. 环境配置 在此之前需要下载一个谷 ...

  6. AJAX--XMLHttpRequest对象

    创建XMLHttpRequest对象 XMLHttpRequest是AJAX的基础. 所有现代浏览器(IE7+.Firefox.Chrome.Safari以及Opera)均内建XMLHttpReque ...

  7. UVA 11520 Fill the Square(模拟)

    题目链接:https://vjudge.net/problem/UVA-11520 这道题我们发现$n\leq 10$,所以直接进行暴力枚举. 因为根据字典序所以每个位置试一下即可,这样的复杂度不过也 ...

  8. 牛客1080D tokitsukaze and Event (双向最短路)

    题目链接:https://ac.nowcoder.com/acm/contest/1080/D 首先建两个图,一个是权值为a的图,一个是权值为b的图. 从s起点以spfa算法跑权值为ai的最短路到t点 ...

  9. pycharm开发flask指定ip、端口无效

    原因分析 是因为使用了pycharm的版本的问题.并不是flask框架本身的问题(不管你是如何设置的flask配置,通过加载config也好,还是通过run的时候传入形参也好,均不影响) 可以很明显的 ...

  10. 概率DP (大概是最入门的题了) lightoj 1248

    有一个骰子,n个面,问所有面都被摇出的期望. 转自**的博客,  因为概率是(n-k)/n  所以期望次数是1/(前面这个数) #include<cstdio> #include<a ...