1. 程式人生 > >ZOJ 2949 Coins of Luck(概率dp)

ZOJ 2949 Coins of Luck(概率dp)

【連結】http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1948

【題意】有一個蛋疼的人打算用投硬幣的方式決定吃A面還是B面,兩種面各有n包,投一次硬幣只吃一包,問到決定完為止投硬幣次數的數學期望

【思路】

數學期望這個東西嘛,我的感覺就是【概率*值的加和】

比如各2包面,那麼(2,2)的期望就要由(2,1)和(1,2)來組合,它們倆各1/2概率再乘各自期望後加一加,注意由於從(2,2)變換成它們還要用一個硬幣,所以還要+1

因此這畫成表格又是一個左邊上邊向我開炮的dp了……

dp[i][j] = 0.5 * dp[i][j-1] + 0.5 * dp[i-1][j] + 1

dp[i][j]是狀態(A面i包,B面j包)時的投硬幣次數期望

再初始化下,1包對1包只用一個硬幣,任何對0包都是0,over


【程式碼】

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <math.h>
#include <iostream>
#include <map>
#include <vector>
#include <set> 
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;

#define MAX_LEN 1005
#define ll long long 
#define mod 100000007

#define MEM(a,al) memset(a,al,sizeof(a))
#define sfx(x) scanf("%lf",&x)
#define sfxy(x,y) scanf("%lf%lf",&x,&y)
#define sdx(x) scanf("%d",&x)
#define sdxy(x,y) scanf("%d%d",&x,&y)
#define pfx(x) printf("%.0f\n",x)
#define pfxy(x,y) printf("%.6f %.6f\n",x,y)
#define pdx(x) printf("%d\n",x)
#define pdxy(x,y) printf("%d %d\n",x,y)
#define getArray(a,len) for(int ia = 0; ia < len; ia++) scanf("%d",&a[ia])
#define printArray(a,len) for(int ia = 0; ia < len; ia++) printf("%d%c",a[ia],(ia==len-1)?'\n':' ')
#define fora(i,n) for(i = 0; i < n; i++)
#define fora1(i,n) for(i = 1; i <= n; i++)
#define foraf(i,n) for(int i = 0; i < n; i++)
#define foraf1(i,n) for(int i = 1; i <= n; i++)
#define ford(i,n) for(i = n-1; i >= 0; i--)
#define ford1(i,n) for(i = n; i > 0; i--)
#define fordf(i,n) for(int i = n-1; i >= 0; i--)
#define fordf1(i,n) for(int i = n; i > 0; i--)

class WriteInfo{
public:
	void info() { printf("[Info] "); }
	void infoEnd() { printf(" [/Info]\n"); }
} W;

const int INF = 1<<29;
const double INFD = 1e20;
const double eps =  1e-6;

int n,m;
double dp[MAX_LEN][MAX_LEN];

int main() {
	int i,j,k;
	int T; 
	
	sdx(T);
	fora(i,1001) dp[0][i] = 0;
	fora(i,1001) dp[i][0] = 0;
	dp[1][1] = 1;
	fora1(i,1000)
		fora1(j,1000)
			dp[i][j] = 0.5 * dp[i][j-1] + 0.5 * dp[i-1][j] + 1;
	while(T--){
		sdx(n);
		printf("%.2f\n",dp[n][n]);
	}
	
	return 0;
}