• 2016 ACM-ICPC NEERC F. Foreign Postcards (概率DP)


    2016 ACM-ICPC NEERC F. Foreign Postcards

    题意:有一串由C、W组成的字符串,每次截取长度为k(1<=k<=n且k随机)的前缀,如果该前缀首位为W,则该前缀取反(即C->W,W->C),放到桌上,否则直接放到桌上;重复前面步骤直至字符串被截为空。求最后桌上W的个数期望。
    思路:定义dp[i]:以s[i]为首的后缀的W个数期望
    则dp[i]=Σ{ (dp[k]+“s[i]到s[k-1]的W或C的个数”)/(n-i) }(i+1<=k<n,s[i]为W时,加C的个数,s[i]为C时直接加W的个数)
    观察式子可以发现,应该倒着推,因为当前状态由后缀状态累加后转移而来。倒着推的过程中,注意累加dp结果以及C,W的个数(这里W,C的个数,指的是当前后缀中所有前缀的C,W个数和,写几项DP转移式可以发现需要维护这些值)

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #define dd(x) cout<<#x<<" = "<<x<<" "
    #define de(x) cout<<#x<<" = "<<x<<endl
    using namespace std;
    typedef long double ld;
    typedef long long ll;
    const int maxn=1e6+10;
    char s[maxn];
    int main()
    {
    	freopen("foreign.in","r",stdin);
    	freopen("foreign.out","w",stdout);
    	scanf("%s",s);
    	int n=strlen(s);
    	ll cntc=0,cntw=0;
    	ld exp=0,ans=0;
    	for (int i=n-1;i>=0;--i)
    	{
    		int p=n-i;
    		if (s[i]=='C')
    		{
    			cntc+=p;
    			ans=(exp+cntw)/p;
    			exp+=ans;
    		}
    		else
    		{
    			cntw+=p;
    			ans=(exp+cntc)/p;
    			exp+=ans;
    		}
    	}
    	printf("%.14Lf",ans);
    	return 0;
    }
    
  • 相关阅读:
    OSI模型白话
    并发
    初始化与清理
    多线程
    recyclerview Adapter
    recyclerview刷新
    surfaceview
    viewgroup绘制流程
    view配置
    项目遇到的问题
  • 原文地址:https://www.cnblogs.com/orangee/p/9735610.html
Copyright © 2020-2023  润新知