博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 4326Game(比较难理解的概率dp)
阅读量:5318 次
发布时间:2019-06-14

本文共 3086 字,大约阅读时间需要 10 分钟。

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.
 

 

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)
 

 

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]。。。依次类推。
         题目地址:
AC代码:
#include
#include
#include
#include
#include
using namespace std;#define maxn 102#define eps 1e-10double 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
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])
=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

 

转载于:https://www.cnblogs.com/suncoolcat/p/3315608.html

你可能感兴趣的文章
linux下vi命令大全
查看>>
JAVA 基础坑
查看>>
oracle 创建自定义的流水号
查看>>
深入理解jQuery框架-框架结构
查看>>
[7.14NOIP模拟4]通讯 题解 (Tarjan缩点+贪心)
查看>>
刷水记录
查看>>
lamp环境安装
查看>>
疫情控制
查看>>
YUI3自动加载树实现
查看>>
String类中的toUpperCase()和toLowerCase()方法
查看>>
python知识思维导图
查看>>
IIS建网站以及建FTP
查看>>
当心JavaScript奇葩的逗号表达式
查看>>
@修饰符--python中的装饰器
查看>>
新工具
查看>>
如何学习-维果茨基
查看>>
App Store最新审核指南(2015年3月更新版)
查看>>
织梦MIP文章内容页图片适配百度MIP规范
查看>>
学习AS3菜鸟起飞吧之—函数(二):函数之返回语句
查看>>
sap basis 常用事务码 --转
查看>>