Codeforces Round #105 (Div. 2) D 概率DP

题目

呃 琢磨了半天还是琢磨出来了,题意有些模糊哈,有w个白色物品,b个黑色物品,A,B轮着抽,A先开始,谁先抽到白色谁赢,若最终都没有抽到白色 则算B赢,抽出来的物品不会放回去,B抽完以后 物品还会有一个额外产生丢失,问A赢的概率为多少

依旧是以目标状态为边界,当前状态到目标状态所需要的概率为 方程

dp[i][j] 代表当前轮到A抽的时候,还有i个白色的j个黑色的A赢的概率为多少

则当前转移可能有四种

1:A抽到了白色的,那么直接赢了,接下来不需要继续,所以没有与其它状态方程有联系

2:A抽到了黑色的,下一次B抽到了白色的 那么A输了,输了就结束了 对下面我们要求的答案无影响,所以不管这一个

3:A抽到了黑色,下一次B又抽到了黑色,且丢失的为白色的,也就是dp[i - 1][j - 2],因为这个都没有产生绝对赢输的状态,所以会对下面的方程转移递推有帮助,所以需要联系上

4:A抽到了黑色,下一次B抽到了黑色,且丢失的为黑色,也就是dp[i][j - 3],这个也没有产生绝对的输赢,所以还是需要联系上

那么边界dp[0][0] = 0,因为轮到A的时候没有可以抽的了,表示都抽光了,这时候按照题目条件算B赢的

还有dp[i][0]轮到A抽的时候 黑色的已经没有了,那么A只能抽白色的  所以肯定赢咯

还有dp[0][j]轮到A的时候白色的没有了,所以必输

double dp[1000 + 55][1000 + 55];

int w,b;

void init() {
	memset(dp,0.00,sizeof(dp));
}

bool input() {
	while(cin>>w>>b) {

		return false;
	}
	return true;
}

void cal() {
	dp[0][0] = 0.00;
	for(int i=1;i<=w;i++)dp[i][0] = 1.00;
	for(int j=1;j<=b;j++)dp[0][j] = 0.00;
	for(int i=1;i<=w;i++) {
		for(int j=1;j<=b;j++) {
			dp[i][j] = (i * 1.0)/(i + j)*1.0;
			if(j >= 2) dp[i][j] += dp[i - 1][j - 2] * (j * 1.0)/(i + j) * (j - 1) * 1.0/(i + j - 1) * (i * 1.0)/(i + j - 2);
			if(j >= 3) dp[i][j] += dp[i][j - 3] * (j * 1.0)/(i + j) * (j - 1)*1.0/(i + j - 1) * (j - 2) * 1.0/(i + j - 2);
		}
	}
	printf("%.10lf\n",dp[w][b]);
}

void output() {

}

int main() {
	while(true) {
		init();
		if(input())return 0;
		cal();
		output();
	}
	return 0;
}
时间: 2024-08-15 00:34:53

Codeforces Round #105 (Div. 2) D 概率DP的相关文章

Codeforces Round #301 (Div. 2) D 概率DP

一个岛上住着三种生物,石头(R).剪刀(S)和布(P).两个不同的生物见面会打架,并且有一方死亡,已知各生物碰见的概率是一样的,求最后岛上只留下剪刀.石头.布的概率. dp[r][s][p] : 石头,剪刀,布分别剩下r,s,p的概率这时,布和石头打一架,将转移到dp[r-1][s][p],而布和石头打架的概率是(p*r)/(r*s + s*p + p*r), 同理,dp[r][s][p]可以转移到状态dp[r][s-1][p] 和dp[r][s][p-1]; 最后统计结果就行. #includ

Codeforces Round #105 (Div. 2) (ABCDE题解)

比赛链接:http://codeforces.com/contest/148 比较简单的一场,最长的一题也才写了30行多一点 A. Insomnia cure time limit per test:2 seconds memory limit per test:256 megabytes ?One dragon. Two dragon. Three dragon?, - the princess was counting. She had trouble falling asleep, and

Codeforces Round #105 (Div. 2) ABCDE

A. Insomnia cure 题解: 水,暴力一下就行了 代码: #include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define ll long long #define CLR(x) memset(x,0,sizeof x) #define SZ(x) ((int)(x).size()) #de

Codeforces Round #271 (Div. 2) D.Flowers DP

D. Flowers We saw the little game Marmot made for Mole's lunch. Now it's Marmot's dinner time and, as we all know, Marmot eats flowers. At every dinner he eats some red and white flowers. Therefore a dinner can be represented as a sequence of several

Codeforces Round #139 (Div. 2)C Barcode DP

#include<iostream> #include<cstdio> #include<cstring> using namespace std ; const int maxn = 1010; const int inf = 0x3f3f3f3f ; int dp[maxn][2] ; char str[maxn][maxn] ; int num[maxn]; int sum_b[maxn]; int sum_w[maxn]; int main() { // fre

Codeforces Round #276 (Div. 1)D.Kindergarten DP贪心

D. Kindergarten In a kindergarten, the children are being divided into groups. The teacher put the children in a line and associated each child with his or her integer charisma value. Each child should go to exactly one group. Each group should be a

Codeforces Round #387 (Div. 2) 747F(数位DP)

题目大意 给出整数k和t,需要产生一个满足以下要求的第k个十六进制数 即十六进制数每一位上的数出现的次数不超过t 首先我们先这样考虑,如果给你了0~f每个数字可以使用的次数num[i],如何求长度为L且满足要求的十六进制数有多少个 dp[i][l]表示使用了前i个数字,已经将L的空位填上了l个的数有多少个 转移方程 dp[i][l] = sigma(dp[i-1][l-j]*C[len-l+j[j]) 其中j是枚举填新的数的个数,C是组合数(选出j个空位填上新数) 有了这个dp后,现在的问题就变

Codeforces Round #157 (Div. 1)B 数位dp

//枚举有几个(7或4),用数位dp的记忆化搜索找有i个(7或4)的数又多少个 //暴力搜索在第i个中选几个 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int mod = 1e9 + 7; int dp[20][20];//第i位有 j个数(7或者4) int bit[20] ; int temp[20]; int luck[20]; int dfs

Codeforces Round #168 (Div. 1)B 树形dp

//给一棵树,每次操作可以将包括顶点1的连通子集的所有点的节点加1或减1 //问最少几次操作使得这棵树的所有顶点的值都为0 //以1为根节点建树 //将加和减分开考虑,用up[u],down[u]表示以u为跟节点的子树中需要加的操作 //最大为up[u] ,需要减的操作最大为down[u] //其余的加和减的操作则可以在处理这两个操作时一起覆盖 //在将u的子数全都处理完后u点的值由于在加了up[u]和减了down[u]后变为 //一个新的值,则对于这个新的值根据它的正负并入up[u]或down