F - Foreign Postcards (dp)

题意:
  1. 对于一叠 n 张卡片,每次随机取前 k 张
  2. 若取到的 k 张的第一张为 W ,则 k 张卡片的状态全部翻转放置桌上。
  3. 若一叠卡片仍有剩余,则继续上述操作
    问最后桌面上为 W 的卡片的期望?
解题思路:

假设一个串为S,S_i表示前后i位,E(s)为串s的期望,len为字符串长度,Wi为前i为中w的个数,那么期望为 ∑ i = 1 n ( 1 / l e n ) ∗ ( w i + E ( S ( n − i ) ) ) \sum_{i=1}^n(1/len)*(w_i+E(S_(n-i))) i=1n(1/len)(wi+E(S(ni)))

那么假设知道了E(S_i),和 S U M = ∑ j = i n E ( S i ) SUM=\sum_{j=i}^nE(S_i) SUM=j=inE(Si) 那么可求E(S_(i+1))

  • 新加上的第一位是W,第一位是W那么第一次取得k位中C和W互换,那么E(S_(i+1))就等于第一步取1位,取两位…到取全长的时候C的数量和加上SUM
    ,每种等概率,再乘上1/len就是ans了
  • 新加上的第一位是C,第一位是C,串不变,那么E(S_(i+1))就等于第一步取1位,取两位…到取全长的时W的数量和加上SUM,每种等概率,再乘上1/len就是ans了

代码:

#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pii;
typedef vector<int>vi;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=1e5+5;
string s; 
int main()
{
	freopen("foreign.in", "r", stdin);
	freopen("foreign.out", "w", stdout);
	cin>>s;
	int len=s.size();
	ll c=0,w=0; //c,w分别计算第一步取1位....取全长所有情况得C,W之和,
	double ans=0; //计算第i位期望
	double sum=0;  //后i位得期望和
	per(i,0,len){
		if(s[i]=='C'){
			c+=len-i;  //在第n-i位 那么在所有情况中(第一步取1位....取全长)就会被加上n-i次
			ans=(sum+w)/(len-i); 
			sum+=ans;
		}
		else{
			w+=len-i; 
			ans=(sum+c)/(len-i);
			sum+=ans;
		}
	}
	printf("%0.10lf",ans);
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值