• 题解-bzoj2554 Color


    Problem

    Please contact lydsy2012@163.com!

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

    (nleq 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,iin(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)相比,可以得到

    [egin{equation} egin{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 imes 1cdot (n-1)}+f_2=frac n2+f_2)

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

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


    最终统计答案

    若一种颜色出现了(c)次,则这个颜色对答案的贡献为(frac cncdot 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
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Mac上搭建Web服务器
    从零开始学ios开发(三):第一个有交互的app
    从零开始学ios开发(二):Hello World!
    C#核心语法
    WP8的新功能-通过一个程序来启动另一个程序
    .NET Web开发技术简单整理
    windows phone 下拉刷新
    使用X.509数字证书加密解密实务(一)-- 证书的获得和管理
    使用X.509数字证书加密解密实务(三)-- 使用RSA证书结合对称加密技术加密长数据
    使用X.509数字证书加密解密实务(二)-- 使用RSA证书加密敏感数据
  • 原文地址:https://www.cnblogs.com/penth/p/10257056.html
Copyright © 2020-2023  润新知