zoukankan      html  css  js  c++  java
  • CTSC2006 歌唱王国

    歌唱王国

    problem

    题解

    (f_i) 表示 (i) 步结束的概率,(g_i) 表示 (i) 步未结束的概率。

    [g_i=f_{i+1}+g_{i+1}\ g_i(frac{1}{m})^L=sum_{j>i 且 j-i是 ext{border}} f_j (frac{1}{m})^{L-(j-i)} ]

    第一个转移表示掷一次骰子dice会发生的事情。

    第二个转移表示拼一个原串上去会发生的事情。(一定会结束)

    solution1

    solution2

    https://jkloverdcoi.github.io/2019/12/13/bzoj-1152-歌唱王国/
    https://www.cnblogs.com/cjyyb/p/10649150.html

    要求的是 (F’(1)) ,将 (1) 式两边对 (x) 求导后代入 (x=1),得到

    [F’(x)+G’(x)=xcdot G’(x)+G(x)\ F’(1)=G(1) ]

    (x=1) 代入 (2) 式,得到

    [G(1)=m^Lsum_{i=1}^n a_icdot F(1) cdot (frac{1}{m})^{L-i}\ G(1)=sum_{i=1}^n a_icdot F(1) cdot m^i\ ]

    注意到 (F(1)=sum f_i=1),所以

    [F’(1)=sum_{i=1}^n a_icdot m^i ]

    于是只需用 KMP 判断给定序列的每个前缀是不是它的 border 就可以了.

    用 %04d 可以达到题目要求的输出效果,当然也可以自己写一下输出.

    时间复杂度 (O(n))

    CO int N=1e5+10;
    int pw[N];
    int str[N],nxt[N];
    
    void real_main(){
    	int n=read<int>();
    	for(int i=1;i<=n;++i) read(str[i]);
    	for(int i=2;i<=n;++i){
    		int j=nxt[i-1];
    		while(j and str[j+1]!=str[i]) j=nxt[j];
    		if(str[j+1]==str[i]) ++j;
    		nxt[i]=j;
    	}
    	int ans=0;
    	for(int i=n;i;i=nxt[i]) ans=add(ans,pw[i]);
    	printf("%04d
    ",ans);
    }
    int main(){
    	int m=read<int>();
    	pw[0]=1;
    	for(int i=1;i<N;++i) pw[i]=mul(pw[i-1],m);
    	for(int T=read<int>();T--;) real_main();
    	return 0;
    }
    

    总结概率生成函数:

    • 优点:处理简洁,易扩展,⽐如可以改成求⽅差,或者说求某⼀项的值。

    • 缺点:列⽅程⽐较不直观,需要⼀定的套路积累和练习(+⼀个/+⼀组)。

  • 相关阅读:
    专职DBA-MySQL体系结构与基本管理
    JSON
    MIME类型
    文件上传下载
    response常用的方法
    2020.11.27小记
    HTTP请求状态码
    1561. Maximum Number of Coins You Can Get
    1558. Minimum Numbers of Function Calls to Make Target Array
    1557. Minimum Number of Vertices to Reach All Nodes
  • 原文地址:https://www.cnblogs.com/autoint/p/12103890.html
Copyright © 2011-2022 走看看