Problem

Please contact lydsy2012@163.com!

题意概要:有 \(n\) 个球排成一列,每个球都有一个颜色,每次随机选出两个球,使得后者染上前者的颜色,求期望操作多少次,才能使得所有球的颜色都一样?

\(n\leq 10^4\)

Solution

思想和这篇差不多,但推导方面可能更详尽

推这题用了大半张草稿纸的说 最近用纸效率剧增啊

考虑只要找出对于每一种颜色\(C\),整个序列最终全部变为\(C\)的情况

设整个序列最终变为颜色 \(i\) 的概率为\(p_i\),期望步数为 \(g_i\),则答案可以表示为

\(Ans=\sum p_ig_i\)

(这里的变量与下文冲突时以下文为准,这里的变量只是作表达作用)

但是要注意,这里的期望步数是在“序列最终变为颜色\(i\)”前提下的期望,是一种条件期望

然后如果想让序列变为颜色 \(i\) ,则对于当前序列而言,只有“是颜色\(i\)”和“不是颜色\(i\)”这两种情况,所以可以将情况化简为一个\(01\)序列,且当前有\(i\)个\(1\),求所有元素变为\(1\)的概率和期望步数


先来解决概率问题

所有操作共有\(n(n-1)\)个,若当前有\(i\)个\(1\),则会改变\(1\)的数量的只有 \(2i(n-i)\)种操作,而且其中会使序列增加一个\(1\)的有其中的一半\(i(n-i)\)种,而使序列减少一个\(1\)的也有\(i(n-i)\)种。即每个回合有\(\frac {i(n-i)}{n(n-1)}\)的概率使\(i\)加一,有\(\frac {i(n-i)}{n(n-1)}\)的概率使\(i\)减一,还有\(1-\frac {2i(n-i)}{n(n-1)}\)的概率没有变化

设\(p_i\)表示当目前有\(i\)个\(1\)时,最终变为颜色\(i\)的概率

由于若已经没有\(1\),则再没有可能使整个序列变为\(1\)了,所以有\(p_0=0\),类似的,有\(p_n=1\)

由分析中\(i\)上升下降概率相同,可以列出\(p_i=\frac {p_{i-1}+p_{i+1}}2,i\in(0,n)\)

由于表達的是等差数列,所以可以轻松得到\(p_i=\frac in\)


再來解決期望问题

考虑到每次操作有一定几率不会对局面进行影响,影响成功的几率为\(\frac {2i(n-i)}{n(n-1)}\),根据期望问题的性质,则期望操作\(\frac {n(n-1)}{2i(n-i)}\)次会对局面影响一次

设\(f_i\)表示当前有\(i\)个\(1\)时序列变为颜色\(i\)的期望步数

则得到方程:\(f_i=\frac {n(n-1)}{2i(n-i)}+\frac 12f_{i-1}+\frac 12f_{i+1}\)

但是这样就错了

因为当前要算的是条件期望,而当局面内有\(i-1\)个\(1\)和有\(i+1\)个\(1\)时整个序列全变\(1\)的概率不一样,由于期望计算是概率乘以权值,所以两者的比例不能简单计算为\(1:1\)

相应的,由之前计算的概率可以得到,若当前局面有\(i-1\)个\(1\),则整个序列全变\(1\)的概率为\(\frac {i-1}n\),相应的,有\(i+1\)个\(1\)时概率为\(\frac {i+1}n\),又由于当前状态只有这两种后继状况,所以两个概率应除以两个概率的和

所以上面的方程需要变化为:

\(f_i=\frac {n(n-1)}{2i(n-i)}+\frac {i-1}{2i}f_{i-1}+\frac {i+1}{2i}f_{i+1}\)

然后利用之前学习的线性高斯消元就可以套路解决了

(这里还是写一下吧,别到时候看这题的时候又推一整版草稿纸)

设\(f_i=k_if_{i+1}+b_i\)

考虑利用这个式子将上面方程进行消元,将这个式子中带入方程右边的第二项,得到

\[f_i=\frac {n(n-1)}{2i(n-i)}+\frac {i-1}{2i}k_{i-1}f_i+\frac {i-1}{2i}b_{i-1}+\frac {i+1}{2i}f_{i+1}
\]

\[(1-\frac {i-1}{2i}k_{i-1})f_i=\frac {i+1}{2i}f_{i+1}+\frac {i-1}{2i}b_{i-1}+\frac {n(n-1)}{2i(n-i)}
\]

\[f_i=\frac {\frac {i+1}{2i}}{1-\frac {i-1}{2i}k_{i-1}}f_{i+1}+\frac {\frac {i-1}{2i}}{1-\frac {i-1}{2i}k_{i-1}}b_{i-1}+\frac {\frac {n(n-1)}{2i(n-i)}}{1-\frac {i-1}{2i}k_{i-1}}
\]

和之前设置的状态\(f_i=k_if_{i+1}+b_i\)相比,可以得到

\[\begin{equation}
\begin{cases}
k_i = \frac {\frac {i+1}{2i}}{1-\frac {i-1}{2i}k_{i-1}} \\
b_i = \frac {\frac {i-1}{2i}b_{i-1}+\frac {n(n-1)}{2i(n-i)}}{1-\frac {i-1}{2i}k_{i-1}}
\end{cases}
\end{equation}
\]

然后由于\(f_0\)没有意义,就无需从此转移,所以得到特殊情况

\(f_1=\frac {n(n-1)}{2\times 1\cdot (n-1)}+f_2=\frac n2+f_2\)

又由于\(f_1=k_1f_2+b_1\),可以得到在\(i=1\)下的特殊情况:\(\begin {cases}k_1=1\\b_1=\frac n2\end{cases}\)

由第一项和上面得到的递推公式,可以推得所有的\(k_i,b_i\),又由于\(f_n=0\),可以轻易得到所有的\(f_i\)


最终统计答案

若一种颜色出现了\(c\)次,则这个颜色对答案的贡献为\(\frac cn\cdot f_c\)

Code

代码还是很短的

#include <cstdio>

const int N=10103;
double k[N],b[N],f[N];
char s[N];int n,ct[26]; int main(){
scanf("%s",s+1);
for(n=1;s[n];++n)
++ct[s[n]-'A'];
--n;k[1]=1,b[1]=0.5*n;
double iv,bs;
for(int i=2;i<n;++i){
iv=0.5/i;
bs=1.0/(1-(i-1)*iv*k[i-1]);
k[i]=(i+1) * iv * bs;
b[i]=((i-1) * iv * b[i-1] + n*(n-1)* iv / (n-i) ) * bs;
} for(int i=n-1;i;--i)
f[i]=k[i]*f[i+1]+b[i]; double ans=0.0;
for(int i=0;i<26;++i)
ans+=1.0*ct[i]/n*f[ct[i]];
printf("%.1lf\n",ans);
return 0;
}

题解-bzoj2554 Color的更多相关文章

  1. bzoj2554: Color

    Description 有n个球排成一列,每个球都有一个颜色,用A-Z的大写字母来表示,我们每次随机选出两个球ball1,ball2,使得后者染上前者的颜色,求期望操作多少次,才能使得所有球的颜色都一 ...

  2. BZOJ2554 color 【概率DP】【期望DP】

    题目分析: 好题. 一开始看错题了,以为是随机选两个球,编号在前的染编号在后的. 但这样仍然能获得一些启发,不难想到可以确定一个颜色,剩下的颜色是什么就无关了. 那么答案就是每种颜色的概率乘以期望.概 ...

  3. 【BZOJ2554】Color 概率神题

    [BZOJ2554]Color Description 有n个球排成一列,每个球都有一个颜色,用A-Z的大写字母来表示,我们每次随机选出两个球ball1,ball2,使得后者染上前者的颜色,求期望操作 ...

  4. PAT甲题题解-1054. The Dominant Color (20)-排序/map

    原本用map,发现超时了,后来便先用数组存储排个序,最后for一遍统计每种颜色出现的次数(每种颜色的首位索引相减+1),找出最多的即可. #include <iostream> #incl ...

  5. HDU1556 Color the ball(差分数组)题解

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  6. 洛谷 P1840 【Color the Axis_NOI导刊2011提高(05)】 题解

    看了一下题解,显然在做无用功啊,而且麻烦了许多,但是这道题真心不难,显然是一个区间修改的题目,然后查询的题目 我的线段树只需要记录一个量:区间和 看了一下其他题解的pushdown函数,发现真心写的很 ...

  7. HDU 1556 Color the Ball 线段树 题解

    本题使用线段树自然能够,由于区间的问题. 这里比較难想的就是: 1 最后更新须要查询全部叶子节点的值,故此须要使用O(nlgn)时间效率更新全部点. 2 截取区间不能有半点差错.否则答案错误. 这两点 ...

  8. 【贪心】Codeforces 349B.Color the Fence题解

    题目链接:http://codeforces.com/problemset/problem/349/B 题目大意 小明要从9个数字(1,2,--,9)去除一些数字拼接成一个数字,是的这个数字最大. 但 ...

  9. HDU 1556 Color the ball 树状数组 题解

    Problem Description N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的"小飞鸽"牌电动 ...

随机推荐

  1. 翻译二--创建一个Web测试计划

    这里主要是翻译jmeter官方文档第4章:创建一个基本的测试计划来测试一个网站.你将创建5个用户来发送请求给两个页面,同时,你将告诉用户去执行两次测试.所以,请求的总和是5(users)*2(requ ...

  2. sql递归查询 根据Id查所有子结点

    Declare @Id Int Set @Id = 0; ---在此修改父节点 With RootNodeCTE(D_ID,D_FatherID,D_Name,lv) As ( Select D_ID ...

  3. .net程序集

    单程序集 多个.dll或exe 文件 多程序集 单个.dll或exe 文件 单程序集 是一个单一 独立明确定义的包,这个包中包含有程序集清单,CIL和类型元数据 多程序集程序集基本由二进制文件组成(称 ...

  4. python模块之序列化

    序列化 什么是序列化 序列化是将字典.列表等数据类型转化成一个字符串的过程 序列化的目的 1. 以某种存储形式使自定义对象持久化(存储) 2. 将对象从一个地方传递到另一个我地方(传输) 3. 使程序 ...

  5. Python Thrift 简单示例

    本文基于Thrift-0.10,使用Python实现服务器端,使用Java实现客户端,演示了Thrift RPC调用示例.Java客户端提供两个字符串参数,Python服务器端计算这两个字符串的相似度 ...

  6. JAVA正确地自定义比较对象---如何重写equals方法和hashCode方法

    在实际应用中经常会比较两个对象是否相等,比如下面的Address类,它有两个属性:String province 和 String city. public class Address { priva ...

  7. Continuous Design

    Continuous Design https://www.martinfowler.com/ieeeSoftware/continuousDesign.pdf T he rising popular ...

  8. Javascript async异步操作库简介

    异步操作知识 在js世界中, 异步操作非常流行, nodejs就是特点基于异步非阻塞. js语言支持的异步语法包括, Promise  async await generator yield. 这些语 ...

  9. Spring 快速开始 配置Spring Framework

    [配置Spring Framework] 1.XML配置依赖关系 bean是由Springframework管理,我们自己编写bean,Spring也内建了bean,比如ApplicationCont ...

  10. mysql 创建存储过程

    mysql 创建存储过程 实例一: CREATE PROCEDURE cp_test() BEGIN declare a int; declare b int; ; ; select a,b; END ...