题目

原题目

点这里

简易题意

包裹里有无限个分布均匀且刚好 \(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}
\]

代码

  1. #define rep(i,__l,__r) for(int i=__l,i##_end_=__r;i<=i##_end_;++i)
  2. #define fep(i,__l,__r) for(int i=__l,i##_end_=__r;i>=i##_end_;--i)
  3. const int MAXN=100;
  4. inline double qkpow(double a,int n){
  5. // printf("Now qkpow : a == %.3lf, n == %d\n",a,n);
  6. double ret=1;
  7. for(;n>0;n>>=1){
  8. if(n&1)ret*=a;
  9. a*=a;
  10. // printf("Now n == %d, a == %.3lf, ret == %.3lf\n",n,a,ret);
  11. }
  12. // printf("ans == %.3lf\n",ret);
  13. return ret;
  14. }
  15. double C[MAXN+5][MAXN+5];
  16. inline void init(){
  17. C[0][0]=1;
  18. rep(i,1,MAXN){
  19. C[i][0]=1;
  20. rep(j,1,i){
  21. C[i][j]=C[i-1][j-1]+C[i-1][j];
  22. }
  23. }
  24. }
  25. signed main(){
  26. #ifdef FILEOI
  27. freopen("file.in","r",stdin);
  28. freopen("file.out","w",stdout);
  29. #endif
  30. int c,n,m;
  31. double a;
  32. init();
  33. while(c=qread()){
  34. qread(n,m);a=0;
  35. if(m>c || m>n || (n-m)&1){
  36. puts("0.000");
  37. continue;
  38. }
  39. rep(i,0,m)rep(j,0,c-m){
  40. a+=(i&1?-1:1)*C[m][i]*C[c-m][j]*qkpow((2*m-2*i+2*j-c)*1.0/c,n);
  41. //此处的快速幂的底数 /c 的原因是为了防止爆 double , 而我们本来就要除以 c^n , 因而我们就在 qkpow 里面处理掉了
  42. }
  43. a=a*C[c][m]/qkpow(2.0,c);
  44. printf("%.3lf\n",a);
  45. }
  46. return 0;
  47. }

练习题

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

  1. #include<cstdio>
  2. #include<vector>
  3. #include<utility>
  4. #include<algorithm>
  5. using namespace std;
  6. #define rep(i,__l,__r) for(int i=__l,i##_end_=__r;i<=i##_end_;++i)
  7. #define fep(i,__l,__r) for(int i=__l,i##_end_=__r;i>=i##_end_;--i)
  8. #define writc(a,b) fwrit(a),putchar(b)
  9. #define mp(a,b) make_pair(a,b)
  10. #define ft first
  11. #define sd second
  12. #define LL long long
  13. #define ull unsigned long long
  14. #define uint unsigned int
  15. #define pii pair<int,int>
  16. #define Endl putchar('\n')
  17. // #define FILEOI
  18. // #define int long long
  19. #ifdef FILEOI
  20. #define MAXBUFFERSIZE 500000
  21. inline char fgetc(){
  22. static char buf[MAXBUFFERSIZE+5],*p1=buf,*p2=buf;
  23. return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXBUFFERSIZE,stdin),p1==p2)?EOF:*p1++;
  24. }
  25. #undef MAXBUFFERSIZE
  26. #define cg (c=fgetc())
  27. #else
  28. #define cg (c=getchar())
  29. #endif
  30. template<class T>inline void qread(T& x){
  31. char c;bool f=0;
  32. while(cg<'0'||'9'<c)f|=(c=='-');
  33. for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
  34. if(f)x=-x;
  35. }
  36. inline int qread(){
  37. int x=0;char c;bool f=0;
  38. while(cg<'0'||'9'<c)f|=(c=='-');
  39. for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
  40. return f?-x:x;
  41. }
  42. template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
  43. template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
  44. template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
  45. template<class T>inline T fab(const T x){return x>0?x:-x;}
  46. inline int gcd(const int a,const int b){return b?gcd(b,a%b):a;}
  47. inline void getInv(int inv[],const int lim,const int MOD){
  48. inv[0]=inv[1]=1;for(int i=2;i<=lim;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
  49. }
  50. template<class T>void fwrit(const T x){
  51. if(x<0)return (void)(putchar('-'),fwrit(-x));
  52. if(x>9)fwrit(x/10);putchar(x%10^48);
  53. }
  54. inline LL mulMod(const LL a,const LL b,const LL mod){//long long multiplie_mod
  55. return ((a*b-(LL)((long double)a/mod*b+1e-8)*mod)%mod+mod)%mod;
  56. }
  57. const int MOD=100;
  58. ull N;int T;
  59. inline int qkpow(int a,ull n){
  60. int ret=1;
  61. for(;n>0;n>>=1,(a*=a)%=MOD)if(n&1)(ret*=a)%=MOD;
  62. return ret;
  63. }
  64. signed main(){
  65. #ifdef FILEOI
  66. freopen("file.in","r",stdin);
  67. freopen("file.out","w",stdout);
  68. #endif
  69. int cas;
  70. while((T=qread())^(cas=0)){
  71. while(T--){
  72. qread(N);
  73. printf("Case %d: ",++cas);
  74. writc((qkpow(4,N-1)+qkpow(2,N-1))%MOD,'\n');
  75. }
  76. Endl;
  77. }
  78. return 0;
  79. }

「题解」「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. spring bean 的作用域

    spring bean 的作用域: 1.单例(singleton):默认是单例模式,也就是说不管给定的bean被注入到其他bean多少次,注入的都是同一个实例. 2.原型(prototype):每次注 ...

  2. 【 js 上传文件】

    上传文件 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> ...

  3. [转]Vue 2.0——渐进式前端解决方案

    前言:框架是什么?为什么要有框架?在众多的框架之中,Vue 独具魅力之处在哪里呢?其背后的核心思想是什么?Vue 究竟火到什么程度?最近发布的 Vue2.0 又做了哪些改进呢?Vue 和 Weex 又 ...

  4. 每天进步一点点------MicroBlaze

             有了前面两个实例的铺垫,下面这个工程就要带大家尝试搭建一个基于MicroBlaze的应用.特权同学也是第一次接插Xilinx的嵌入式开发平台,跑了一个流程下来,正如所料,和Alter ...

  5. mybatis报错:A query was run and no Result Maps were found for the Mapped Statement、、Property [login_ip] not found on type [com.thinkgem.jeesite.common.permission.entity.PremissUser]问题解决

    今天在做ssm项目的时候出现了: 先是出现 了错误: mybatis报错:A query was run and no Result Maps were found for the Mapped St ...

  6. Makefile中的wildcard/notdir/patsubst

    在Makefile规则中,通配符会被自动展开. 但在变量的定义和函数引用时,通配符将失效.这种情况下如果需要通配符有效,就需要使用函数“wildcard”,它的用法是:$(wildcard PATTE ...

  7. Linux服务器时间设置及同步

    闲余:夏日将到,园区计划五一期间进行大面积的电网停电检修,运维同学因此将公司测试服务器提前关闭了.收假后,测试告诉我,他发现一个bug--一段定时任务程序未执行,我的第一反应就是--会不会是假期测试服 ...

  8. Flask 教程 第十六章:全文搜索

    本文翻译自The Flask Mega-Tutorial Part XVI: Full-Text Search 这是Flask Mega-Tutorial系列的第十六部分,我将在其中为Microblo ...

  9. truffle编译合约常见问题及其在私链上的部署与交互

    一.初始化truffle项目 truffle init //初始化truffle项目文件夹 将写好的合约文件放到contract文件夹中 truffle  compile  //编译合约 (注意!! ...

  10. Linux常用命令英文全称与中文解释 (pwd、su、df、du等)

    https://blog.csdn.net/qq_40334837/article/details/83819735 Linux常用命令英文全称与中文解释 apt: Advanced Packagin ...