Millionare_离散化&&DP


相当于在不同模块之间来回移动


#include<cstdio>
#include<iostream>
#include<cstring>

using namespace std;

//最大可能的模块数 
const int maxn = 1 << 15 + 10;
//轮数 
int M;
//赌赢概率 
double P;
//本钱 
int X;
//dp[i][j] 表示第i轮每个模块赢到100W的概率
//这里采用滚动数组节约内存 
double dp[2][maxn];
//新技能get, 滚动数组 
double *prv = dp[0], *nxt = dp[1];

int main ()
{
	memset(dp, 0, sizeof(dp)); 
		
	cin >> M >> P >> X;
		
	int n = 1 << M;
	prv[n] = 1.0;
		
	for(int i= 0; i< M; i++){
		for(int j= 0; j<= n; j++){
				
			int ub = j > n-j ? n-j : j;
				
			double temp = 0.0;
			//枚举可能跨越的模块的数 
			for(int k= 0; k<= ub; k++)
				if(temp < P*prv[j+k] + (1-P)*prv[j-k])
					//这把赌赢的概率*赌赢后赢到100W的概率
					//这把赌输的概率*赌输后赢到100W的概率 
					temp = P*prv[j+k] + (1-P)*prv[j-k];
						
			nxt[j] = temp;
		}
		//新技能get, 滚动数组 
		swap(prv, nxt);
	}
	
	//判断 X 在哪个模块中 
	int pos = (double) X / 1000000 * n;
		
	printf("%f\n", prv[pos]);
	
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值