题目

原题目

点这里

简易题意

包裹里有无限个分布均匀且刚好 \(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. SOC-training image镜像内核文件(DE1-soc软件实验”hello_word")

    在DE1-soc软件实验”hello_word"此实验中,我开始并没有将SOC-training image镜像内核文件用win32disk写入sd卡中,直接插入sd卡,发现putty连接c ...

  2. LOJ138 类欧几里得算法

    类欧几里得算法 给出 \(T\) 组询问,每组用 \(n, a, b, c, k_1, k_2\) 来描述.对于每组询问,请你求出 \[ \sum_{x = 0} ^ {n} x ^ {k_1} {\ ...

  3. HTML5学习(4)文本元素

    使用VSCode编辑器,内置emmet插件. ctrl+/ 注释/取消注释 ctrl+enter 新起一行 ctrl+shift+enter 往上新起一行 h$*4>lorem10 <h1 ...

  4. ONESHELL

    没有加 .ONESHELL 的时候,片段中的各行 shell 彼此独立. 加了 .ONESHELL 后,各行shell 可以看作一行 shell. <1> .PHONY: all all: ...

  5. lminus

    lminus是Synopsy自带的tcl list 操作command. 顾名思义,可以将两个list相减,即过滤掉两个list中相同的element,生成一个新的list,其实是用lsearch与l ...

  6. Docker 基本命令和使用

    Docker 基本命令 systemctl start docker : 启动 Docker systemctl stop docker : 停止 Docker systemctl restart d ...

  7. 《深入浅出WPF》学习总结之Binding

    一.前言 友好的图形用户界面(Graphics User Interface ,GUI)的流行也就是近十来年的事情,之前应用程序与用户的交互是通过控制台界面(Console User Interfac ...

  8. iview渲染函数

    <Table border :columns="discountColumns" :data="discountData.rows"></Ta ...

  9. Linux06——安装JDK、Tomcat、Eclipse

    一.安装JDK(具体解压命令在Linux02中) ①将JDK解压到opt目录下(opt就是文件夹) ②配置环境变量  vim  /etc/profile JAVA_HOME=/opt/jdk1.8.0 ...

  10. IntelliJ IDEA 2017.3尚硅谷-----设置界面