题目

原题目

点这里

简易题意

包裹里有无限个分布均匀且刚好 \(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. Apache Kafka(三)- Kakfa CLI 使用

    1. Topics CLI 1.1  首先启动 zookeeper 与 kafka > zookeeper-server-start.sh config/zookeeper.properties ...

  2. vue 使用 jsonp 请求数据

    vue 使用 jsonp 请求数据 vue请求数据的时候,会遇到跨域问题,服务器为了保证信息的安全,对跨域请求进行拦截,因此,为了解决vue跨域请求问题,需要使用jsonp. 安装jsonp npm ...

  3. mysql渗透过程

    1 打开目标站点:www.xxx.com 2 注册账号并登录,大概找下注入点,没找到 3 用namp -A -T4 目标站点扫描开放的服务 发现mysql等 4 猜弱口令 + 字典  对mysql进行 ...

  4. IDEA格式化代码快捷键失灵原因

    网易云音乐快捷键与IDEA快捷键冲突了!!!!!!!坑爹

  5. AS报错:Error:Execution failed for task ':app:preDebugAndroidTestBuild'. > Conflict with dependency 'com.and

    build->Rebuid-project 寻找错误根源: 报错里可以发现: Resolved versions for app (26.1.0) and test app (27.1.1) d ...

  6. 使用docker踩过的坑(二)

    关于docker的部署,我这里不多说了 下面写一些最近经常用到的命令: docker下载镜像: docker pull 镜像名 docker查看已下载的所有镜像: docker images dock ...

  7. javacript onclick事件中传递参数

    var user = {id:1, name:'zhangsan'}; var object = '<a onclick="conversion(' + JSON.stringify( ...

  8. libcurl库的简介(一)

    一.Libcurl库简介 LibCurl是免费的客户端URL传输库,支持FTP,FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, FILE ,LDAP ...

  9. SpringMVC重定向(redirect)传参数,前端EL表达式接受值

    由于重定向相当于2次请求,所以无法把参数加在model中传过去.在上面例子中,页面获取不到msg参数.要想获取参数,可以手动拼url,把参数带在后面.Spring 3.1 提供了一个很好用的类:Red ...

  10. Bugku-CTF加密篇之+[]- (+++++ +++++ [->++ +++++ +++<] >++.+ +++++ .<+++ [->-- -<]>- -.+++ +++.< ++++[ ->.........)

    +[]- +++++ +++++ [->++ +++++ +++<] >++.+ +++++ .<+++ [->-- -<]>- -.+++ +++.< ...