hdu 4649——Professor Tian

因为只有20位,而且&,|,^都不会进位,那么一位一位地看,每一位不是0就是1,这样求出每一位是1的概率,再乘以该位的十进制数,累加,就得到了总体的期望。

f[i][j]表示该位取前i个数,运算得到j(01)的概率是多少。

f[i][1]=f[i-1][1]*p[i]+根据不同运算符和第i位的值运算得到1的概率。

f[i][0]同理。

初始状态:f[0][0~1]=01(根据第一个数的该位来设置)

每一位为1的期望 f[n][1]

 

#include<iostream>
#include<cstdio>
using namespace std;
int num[300];
double p[300];
char c[300];
double dp[300][2];
int main()
{
	int n;
	int cnt=0;
	while(~scanf("%d",&n))
	{
		for(int i=1;i<=n+1;i++)
			scanf("%d",&num[i]);
		for(int i=2;i<=n+1;i++)
			cin>>c[i];
		for(int i=2;i<=n+1;i++)
			scanf("%lf",&p[i]);
		double ans=0.0;
		for(int i=1;i<=20;i++)
		{
			dp[1][1]=num[1]&1;
			dp[1][0]=!dp[1][1];
			num[1]>>=1;
			for(int j=2;j<=n+1;j++)
			{
				int k=num[j]&1;
				num[j]>>=1;
				if(c[j]=='|')
				{
					if(k==1)
					{
						dp[j][1]=1*(1-p[j])+p[j]*dp[j-1][1];
						dp[j][0]=1-dp[j][1];
					}
					else
					{
						dp[j][1]=dp[j-1][1]*(1-p[j])+p[j]*dp[j-1][1];
						dp[j][0]=1-dp[j][1];
					}
					continue;	
				}
				if(c[j]=='&')
				{
					if(k==1)
					{
						dp[j][1]=dp[j-1][1]*(1-p[j])+p[j]*dp[j-1][1];
						dp[j][0]=1-dp[j][1];
					}
					else
					{
						dp[j][1]=0+p[j]*dp[j-1][1];
						dp[j][0]=1-dp[j][1];
					}
					continue;	
				}
				if(c[j]=='^')
				{
					if(k==1)
					{
						dp[j][1]=dp[j-1][0]*(1-p[j])+p[j]*dp[j-1][1];
						dp[j][0]=1-dp[j][1];
					}
					else
					{
						dp[j][1]=dp[j-1][1]*(1-p[j])+p[j]*dp[j-1][1];
						dp[j][0]=1-dp[j][1];
					}
					continue;	
				}
			}
			ans+=(1<<(i-1))*dp[n+1][1];
		}
		printf("Case %d:\n%.6f\n",++cnt,ans);	
	}
	return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值