概率DP&期望杂题

1.http://zhengruioi.com/problem/450

​/*f[i][j]:前i个人,有j个人正常出局的概率

f[i][j]+=f[i-1][j]*P1+f[i-1][j-1]*p2;
        留下来/被日死     正常出局 
p  别人出局后自己被日死的概率 
P2=(1-p)^(j-1);
P1=(1-P1)

f[i][k]*P2 前K个过后都没有被日死
最后再*inv(1/n),这一轮出局概率 */
#include<bits/stdc++.h>
#define rep(i,a,b) for(ll i=(a);i<=(b);i++)
#define ll long long
using namespace std;
const ll mod=258280327;
const ll N=3e3;
ll f[N][N],A[N],B[N],n,x,y,p;
ll power(ll a,ll b){ll ans=1;for(;b;b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod;return ans;}
int main()
{
	ll t;scanf("%lld",&t);
	while(t--){
		scanf("%lld%lld%lld",&n,&x,&y);
		p=x*power(y,mod-2)%mod;
		A[0]=1;rep(i,1,n)A[i]=A[i-1]*p%mod;
		B[0]=1;rep(i,1,n)B[i]=B[i-1]*((1-p)%mod+mod)%mod;
		memset(f,0,sizeof(f));f[1][0]=1;
		rep(i,2,n)rep(j,0,i-1)f[i][j]=f[i-1][j]*((1-B[j])%mod+mod)%mod+f[i-1][j-1]*B[j-1]%mod;
		rep(i,0,n-1){
			ll ans=0;
			rep(j,1,n)ans=(ans+f[j][i]*B[i])%mod;
			cout<<ans*power(n,mod-2)%mod<<" ";
		}puts(" ");
	}
	return 0;
}​

2.https://www.luogu.org/problemnew/show/CF148D#sub 

/*f[w][b]表示袋子里有w个白的,b个黑的赢得概率
显然 f[][0]=1,f[0][]=0 作为边界,可以记忆化搜索
每次分两种情况:1.A直接取到白球赢的概率 =w/(w+b);
因为先取到白球谁先赢,那么B不能赢
2.A取到黑球, B取到黑球,然后跑出一个黑球
p=b/(w+b)*(b-1)/(w+b-1)*(b-2)/(w+b-2)*f[w][b-3]; (b>=3) 
A取到黑球,B取到黑球,然后跑出一个白球 
p=b/(w+b)*(b-1)/(w+b-1)*w/(w+b-2)*f[w-1][b-2] w&&b>=2*/
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
using namespace std;
const int N=2e3;
int w,b,v[N][N];
double f[N][N];
double work(int w,int b){
	
	if(w==b&&w==0)return 0.0;
	if(b==0)return 1.0;
	if(w==0)return 0.0;
	if(v[w][b])return f[w][b];v[w][b]=1;
	double res=1.0*w/(w+b);
	if(b>=3) res+=(b*1.0/(w+b))*((b-1)*1.0/(w+b-1))*((b-2)*1.0/(w+b-2))*work(w,b-3); 
	if(b>=2) res+=(b*1.0/(w+b))*((b-1)*1.0/(w+b-1))*(w*1.0/(w+b-2))*work(w-1,b-2);
	return f[w][b]=res;
}
int main()
{
	memset(v,0,sizeof(v));
	while(~scanf("%d%d",&w,&b)){
		work(w,b);
		printf("%.9lf\n",work(w,b));
	}
	return 0;
}

3.https://www.luogu.org/problemnew/show/UVA12230

/*有个人每天要去公司上班,每次会经过N条河,家和公司的距离为D,默认在陆地的速度为1,
给出N条河的信息,包括起始坐标p,宽度L,以及船的速度v。船会往返在河的两岸,人到达
河岸时,船的位置是随机的(往返中)。问说人达到公司所需要的期望时间。

因为船的位置是随机的,那我们考虑最长过河时间和最短过河时间
最长:3*L/v;
最短:L/v;
由于算的是期望,那么每条河的期望时间就是
sigma(i=1~3)i*L/v*p; p是概率
我们再观察一下这个式子,这不就是算平均数吗?
那么过每条河的期望时间就等于2*L/v;
然后就可以愉快的计算了*/
#include<bits/stdc++.h>
using namespace std;
int n,D,p,L,v,Case=0;
double ans=0;
int main()
{
	while(~scanf("%d%d",&n,&D)){
		if(n==0&&D==0)return 0;
		ans=0.0;
		while(n--){
			scanf("%d%d%d",&p,&L,&v);
			D-=L;
			ans+=2.0*L/v;
		}
		ans=ans+1.0*D;
		printf("Case %d: %.3lf\n\n",++Case,ans);
	}
	return 0;
}

4.https://www.luogu.org/problemnew/show/SP1026

/*甩一个n面的骰子,问每一面都被甩到的期望次数是多少。
f[i]表示甩出了i~n面的期望次数 
还是倒推吧 
f[i]=(f[i]+1)*i/n+(f[i+1]+1)*(n-i)/n;
移项可得
f[i]=f[i+1]+n/(n-i);
就可以愉快的计算了*/
#include<bits/stdc++.h>
#define per(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
double f[2000];
int n,T;
int main()
{
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		f[n]=0;
		per(i,n-1,0)f[i]=f[i+1]+n*1.0/(n-i);
		printf("%.2lf\n",f[0]);
	}
	return 0;
}

 

期望dp和概率dp是两种不同的动态规划方法。 期望dp是指通过计算每个状态的期望值来求解最终的期望。在期望dp中,我们通常定义dp\[i\]表示在第i个状态时的期望值,然后通过状态转移方程来更新dp数组,最终得到最终状态的期望值。期望dp通常用于求解期望,例如求解骰子的期望点数、求解抽奖的期望次数等。 概率dp是指通过计算每个状态的概率来求解最终的概率。在概率dp中,我们通常定义dp\[i\]表示在第i个状态时的概率,然后通过状态转移方程来更新dp数组,最终得到最终状态的概率概率dp通常用于求解概率,例如求解抛硬币出现正面的概率、求解从一副牌中抽到红心的概率等。 总结来说,期望dp和概率dp的区别在于它们所计算的是不同的值,期望dp计算的是期望值,而概率dp计算的是概率值。 #### 引用[.reference_title] - *1* [概率/期望dp专](https://blog.youkuaiyun.com/qq_34416123/article/details/126585094)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【动态规划】数学期望/概率DP/期望DP详解](https://blog.youkuaiyun.com/weixin_45697774/article/details/104274160)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值