[BZOJ]4844: [Neerc2016]Foreign Postcards 概率DP

本文探讨了一个关于邮票翻转的数学问题,通过概率计算和动态规划的方法,求解了邮票在特定规则下翻转后仍放反的期望数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

ls是一名集邮爱好者,他专门有一个栈来存放他的所有的邮票,但ls同时也是一名很粗心的人,有一些邮票可能放反了(上下颠倒),有一天他想把他的邮票拿出来向他的妹子炫耀,但因为有一些邮票可能反了,于是ls就想把那些邮票矫正方向,但ls特别懒,他觉得一张一张矫正太费时间了,即使是要给妹子看的,他也不想费太多时间,于是ls就想出了一种奇迹淫巧:
1.假设栈中还剩n张邮票,他每次从1到n中随机取一个整数k,然后取出栈中最上面的k张。
2.他会查看这k张中最上面的一张,如果它放反了,那么他就直接把这k张全部倒过来。
3.他直接把这k张放到桌上,然后准备给妹子炫耀,并且之后对这k张不做任何操作。
4.如果栈中还剩余邮票,那么回到步骤1。
当然,这毕竟是奇迹淫巧,而且是ls想出来的,桌上还是有可能有一些邮票放反了
那么ls想询问期望有多少张邮票放反了?

Solution

首先算出每张牌作为第一张的概率,第111张是111,第222张是1n1\over nn1,第333张是1×1n+1n×1n−1=1n−11\times {1\over n}+{1\over n}\times {1\over n-1}={1\over n-1}1×n1+n1×n11=n11,然后就发现第iii张就是1n−i+2(i≥2){1\over n-i+2}(i\ge2)ni+21(i2)
设上面的这个概率为ppp,第iii张牌翻转的概率为fif_ifi,那么有:fi=p+(1−p)fi−1(si=W)f_i=p+(1-p)f_{i-1}(s_i=W)fi=p+(1p)fi1(si=W)fi=(1−p)fi−1(si=C)f_i=(1-p)f_{i-1}(s_i=C)fi=(1p)fi1(si=C)
前后之间的联系还是挺妙的。

Code

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,int>
const int Maxn=1000010;
const int inf=2147483647;
int n;long double f[Maxn][2];//0不翻 1翻 
char str[Maxn];
int main()
{
    scanf("%s",str+1);n=strlen(str+1);
    if(str[1]=='C')f[1][0]=1,f[1][1]=0;
    else f[1][0]=0,f[1][1]=1;
    long double ans=0;
    for(int i=2;i<=n;i++)
    {
        long double p=1.0/((long double)n-i+2);
        if(str[i]=='C')f[i][0]=p+(1-p)*f[i-1][0];
        else f[i][0]=(1-p)*f[i-1][0];
        f[i][1]=1-f[i][0];
        if(str[i]=='C')ans+=f[i][1];else ans+=f[i][0];
    }
    printf("%.15Lf",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值