Foreign Postcards

Posted ph = x

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Foreign Postcards相关的知识,希望对你有一定的参考价值。

题意:

给定 n 张排成一堆的的卡片,每一次从堆顶上等概率随机取出 [1~当前卡片数] 个卡片,如果堆顶的卡片是反面朝上,

则将所有取出的卡片翻转,求问期望取出多少个反面朝上的卡片。

 

解法:

考虑dp,首先有期望的可加性得

$ans = \sum_{i=1}^n{ P(card_i \  is \  reversed \  when \  got) }$

这样考虑求后面的概率。

用 $f(i)$ 表示以 $i$ 为取出的卡片的顶上的卡片的概率。

$f(1) = 1$

$f(i) = \sum{ \frac{f(j)}{n-j+1} }$

这样记$h(i,0), h(i,1)$ 分别表示第 $i$ 张卡片被一张正面朝上的卡消去 和 被一张反面朝上的卡消去的概率。

从而有

$$h(i,0) = \sum{1 \leq j \leq i, S(j-1) = ‘C‘}_{ f(j) \frac{n-i+1}{n-j+1} }$$

$h(i,1)$ 递推式同理。

对两个式子记一下前缀和,$O(n)$

 

技术分享
#include <iostream>
#include <cstdio>
#include <cstring>

#define LD double
#define N 1000010

using namespace std;

int n;
LD f[N];
char S[N];

int main()
{
    freopen("foreign.in", "r", stdin);
    freopen("foreign.out", "w", stdout);
    while(~scanf("%s",S))
    {
        n = strlen(S);
        f[1] = 1;
        f[2] = 1.0 / (LD)n;
        for(int i = 2;i < n;i++)
            f[i+1] = f[i] + f[i] / (n-i+1);
        LD sumC = 0, sumW = 0, ans = 0;
        for(int i = 1;i <= n;i++)
        {
            if(S[i-1] == C) sumC += f[i] / (n-i+1.0);
            else sumW += f[i] / (n-i+1.0);
            if(S[i-1] == C) ans += (n-i+1.0) * sumW;
            else ans += (n-i+1.0) * sumC;
        }
        printf("%.10lf\n", ans);
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}
View Code

 

以上是关于Foreign Postcards的主要内容,如果未能解决你的问题,请参考以下文章

android.database.sqlite.SQLiteException:在“Foreign”附近:语法错误(代码 1):

Android Room FOREIGN KEY 约束失败(代码 787)

SqlException:INSERT 语句与使用 EF 代码优先 C# 的 FOREIGN KEY 约束冲突

FOREIGN KEY 约束失败(代码 787)[NO ANDROID ROOM]

错误代码1833 Cannot change column used in a foreign

与 FOREIGN KEY 冲突