HDU 4326Game(比較難理解的概率dp)
Game
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 229 Accepted Submission(s): 85
Problem Description
There are N people playing a game. The rules of the game are described as follows:
Initially, there are N people numbered from 1-N. And they are arranged in a queue by the order from 1-N. Each round, only 4 people get into the game and each people has equally probability to win the game. The winner can continue to games, the loser will go to the end of the queue according to the order before this round (if someone was the winner before this round, we can consider he was the head of the queue).
The first round of game, the first four people start to play the game. If someone continuously wins the game M times, he will become the final winner.
Now I want to know the probability for the K-th people to become the final winner.
Initially, there are N people numbered from 1-N. And they are arranged in a queue by the order from 1-N. Each round, only 4 people get into the game and each people has equally probability to win the game. The winner can continue to games, the loser will go to the end of the queue according to the order before this round (if someone was the winner before this round, we can consider he was the head of the queue).
The first round of game, the first four people start to play the game. If someone continuously wins the game M times, he will become the final winner.
Now I want to know the probability for the K-th people to become the final winner.
Input
The first line of input contains T, the number of test cases.
Flowing T line, each line contains 3 integer N, M, K.(4<=N<=10, M<=10,K<=N)
Flowing T line, each line contains 3 integer N, M, K.(4<=N<=10, M<=10,K<=N)
Output
Each output should occupy one line. Each line should start with "Case #i : ", followed by the answer round to six decimal places.
Sample Input
3
4 1 1
5 1 5
5 2 1
Sample Output
Case #1: 0.250000
Case #2: 0.000000
Case #3: 0.217626
Author
BJTU
Source
Recommend
zhoujiaqi2010
題目大意:給出n個人每次4人進行比賽其他人等待,勝者繼續,負者排到最後,連續或得m次勝利的人成為最終的贏家,求第k個人最終獲得勝利的概率是多少?對於這題,我們首先確立一個這樣的模型:
x1先贏了i局,正在於x2,x3,x4賭鬥,後面依次有x5,x6,……,xn等待。用P[i][j]表示x1先贏了i局的情況下,當前的xj獲勝的概率。
腦袋不靈光了,坑了一晚上才坑出來。。
下面的一段文字轉自茂茂:可以參見大牛的部落格
因為要考慮連續贏的情況並且每次動作只和第一個人有關,設第一維表示第一個人連續贏的次數。第二維表示第j個人此次贏的概率。
dp[i][j]表示第一個人已經贏了i次,當前第j個人能贏的概率。
最終也就是要求dp[0][k].表示第一個人一次都沒贏時第k個人贏的概率。
當j=1時,dp[i][j]=1/4*dp[i+1][j]+3/4*dp[1][n-2] //該人要麼贏,要麼輸,輸的話,後面有兩個人排在他後面,所以他在n-2的位置。
當j=2時,dp[i][j]=1/4*dp[i+1][n-2]+1/4*dp[1][j-1]+2/4*dp[1][n-1]
當j=3時,dp[i][j]=1/4*dp[i+1][n-1]+1/4*dp[1][n-1]+1/4*dp[1][1]+1/4*dp[1][n]
當j=4時,dp[i][j]=1/4*dp[i+1][n]+2/4*dp[1][n]+1/4*dp[1][1];
當j>4時,dp[i][j]=1/4*dp[i+1][j-3]+3/4*dp[1][j-3]
注意
1、i<m,
2、dp[m][1]=1,表示第一個人已經贏了m次,結束。
此轉移方程,前後都有,不能直接通過遞推或迭代求出,所以選用高斯消元求解。
一共有m*n個未知數,所以可以求一個n*m元的一次方程。
實際上dp[0][1]即為x[1],dp[0][2]即為x[2]。。。依次類推。
題目地址:Game
AC程式碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
#define maxn 102
#define eps 1e-10
double g[maxn][maxn];
double x[maxn];
int n,m,k;
void add(int cnt,int i,int j,double val)
{
int t=i*n+j;
if(i==m)
{
if(j==1) //p[m][1]=1;結束
g[cnt][m*n+1]+=-1.0*val; //方程的右邊
return;
}
g[cnt][t]+=val;
}
void gauss(int n,int m)
{
int row,col,i,j,k;
for(row=1,col=1;row<n,col<m;row++,col++)
{
k=row;
for(i=row+1;i<=n;i++) //列主元
if(fabs(g[i][col])>fabs(g[k][col]))
k=i;
if(k!=row) //行交換
{
for(i=col; i<=m; i++)
swap(g[k][i],g[row][i]);
}
for(i=row+1; i<=n; i++) //主元不是0把下面的行第一個值全部變為0
{
if(fabs(g[i][col])<eps)
continue;
double t=g[i][col]/g[row][col];
g[i][col]=0.0;
for(j=col+1;j<=m;j++)
g[i][j]-=t*g[row][j];
}
}
for(i=n;i>=1;i--) //回代求解
{
x[i]=g[i][m];
for(j=i+1;j<=n;j++)
x[i]-=x[j]*g[i][j];
x[i]/=g[i][i];
}
}
int main()
{
int i,j,cs,nn=0;
scanf("%d",&cs);
while(cs--){
scanf("%d%d%d",&n,&m,&k);
memset(g,0,sizeof(g));
int cnt=0;
for(i=0;i<m;i++) //i==m的時候只能在右邊出現
for(j=1;j<=n;j++)
{
cnt++;
add(cnt,i,j,1.0);
if(j==1)
{
add(cnt,i+1,j,-0.25);
add(cnt,1,n-2,-0.75);
}
else if(j==2)
{
add(cnt,i+1,n-2,-0.25);
add(cnt,1,1,-0.25);
add(cnt,1,n-1,-0.5);
}
else if(j==3)
{
add(cnt,i+1,n-1,-0.25);
add(cnt,1,1,-0.25);
add(cnt,1,n-1,-0.25);
add(cnt,1,n,-0.25);
}
else if(j==4)
{
add(cnt,i+1,n,-0.25);
add(cnt,1,n,-0.5);
add(cnt,1,1,-0.25);
}
else
{
add(cnt,i+1,j-3,-0.25);
add(cnt,1,j-3,-0.75);
}
}
gauss(cnt,cnt+1);
printf("Case #%d: %.6lf\n",++nn,x[k]);
}
return 0;
}
相關文章
- HDU 3853 LOOPS(概率dp)OOP
- 2014鞍山網路賽 E題||hdu 5001 概率dp
- 概率DP入門題
- 概率DP總結 by kuangbin
- hdu 4089||2011年北京現場賽I題 概率dp(公式不好推)公式
- SGU 495 Kids and Prizes:期望dp / 概率dp / 推公式公式
- codeforces 148 D 概率dp
- HDU4546 比賽難度 (優先佇列)佇列
- POJ 3744 概率dp+矩陣矩陣
- 全概率公式理解公式
- codeforces 148 D Bag of mice(概率dp)
- HDU 4669 Mutiples on a circle (DP , 統計)
- 條件概率、全概率、貝葉斯公式理解公式
- VBA和Python到底哪個比較難學Python
- Codeforces 148D Bag of mice (概率dp)
- 【基礎dp】HDU 1260 Tickets
- hdu 3401 單調佇列+DP佇列
- HDU 4455 Substrings(預處理+dp)
- Python解惑:整數比較 is ==的比較Python
- hdu ---(4517)小小明系列故事——遊戲的煩惱(Dp)遊戲
- 怎麼理解今年 CV 比較火的擴散模型(DDPM)?模型
- 【演算法學習筆記】概率與期望DP演算法筆記
- HDU 6415 Rikka with Nash Equilibrium (DP)UI
- HDU 3853 LOOPS:期望dp【網格型】OOP
- 【dp】HDU - 1069 Monkey and BananaNaN
- hdu4374單調佇列+dp佇列
- HDU 5119 Happy Matt Friends(DP)APP
- HDU 5326 Work (基礎樹形dp)
- hdu 4123 樹形DP+RMQMQ
- Integer的比較
- 主流備份軟體比較及特點分析,NBU/TSM/Legato/DP/Bakbone
- js 深比較和淺比較JS
- hdu5435 數位dp(大數的處理)
- 從根上理解 MySQL 的字符集和比較規則MySql
- lightoj 1030 Discovering Gold (基礎概率dp)Go
- HDU6415:Rikka with Nash Equilibrium(dp)UI
- 【基礎dp】HDU 1176 免費餡餅
- HDU 5067 Harry And Dig Machine(狀壓dp)Mac