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
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.
Flowing T line, each line contains 3 integer N, M, K.(4<=N<=10, M<=10,K<=N)
4 1 1
5 1 5
5 2 1
Case #2: 0.000000
Case #3: 0.217626
题目大意:
给出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元的一次方程。
#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 4326Game(比较难理解的概率dp)的更多相关文章
- HDU 4405:Aeroplane chess(概率DP入门)
http://acm.split.hdu.edu.cn/showproblem.php?pid=4405 Aeroplane chess Problem Description Hzz loves ...
- 2015多校第7场 HDU 5378 Leader in Tree Land 概率DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5378 题意:一棵n个节点的树.对其节点进行标号(1~n).求恰好存在k个节点的标号是其节点所在子树的最 ...
- HDU 4336 Card Collector(动态规划-概率DP)
Card Collector Problem Description In your childhood, do you crazy for collecting the beautiful card ...
- [HDU 3689]Infinite monkey theorem (KMP+概率DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3689 黄老师说得对,题目只有做wa了才会有收获,才会有提高. 题意:一个猴子敲键盘,键盘上有n个键,猴 ...
- [HDU 4336] Card Collector (状态压缩概率dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4336 题目大意:有n种卡片,需要吃零食收集,打开零食,出现第i种卡片的概率是p[i],也有可能不出现卡 ...
- HDU 1203 【01背包/小数/概率DP】
I NEED A OFFER! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tot ...
- HDU 2955 【01背包/小数/概率DP】
Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- HDU 5607 graph(矩阵优化+概率DP)
该题非常easy想到求概率的转移方程:用d[i][j]表示第i步,走到j点的概率. 可是该题的k高达1e9.所以依照套路.要用矩阵相乘来优化. 第一次写矩阵相乘. 大概的意思就是利用矩阵实现递推. 而 ...
- hdu 4586 Play the Dice(概率dp)
Problem Description There is a dice with n sides, which are numbered from 1,2,...,n and have the equ ...
随机推荐
- C#学习日志 day7 --------------LINQ与Lamda语句的初步尝试以及XML的生成
LINQ是一种集成在计算机语言里的信息查询语句,是c#3.0中最惹人瞩目的功能. 在C#中,LINQ语句有两种写法. 第一种写法与SQL语句类似: IEnumerable<Customer> ...
- struts2笔记03-ActionContext
1.概念 ActionContext是action的上下文,它包括action执行所需要的对象.struts2对每一个action都会创建一个新的ActionContext实例,同Action一样,是 ...
- WebRTC 音视频开发
WebRTC 音视频开发 webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译 ...
- OSG坐标系统
1.世界坐标 世界坐标系描述的是整个场景中所有的对象,可以理解为绝对坐标系,所有对象的位置都是绝对坐标.从整体上考虑,它为所有对象的位置提供一个绝对的参考标准,从而避免了物体之间由于独 ...
- Case when 的用法,简单Case函数
Case when 的用法,简单Case函数 简单CASE表达式,使用表达式确定返回值. 语法: CASE search_expression WHEN expression1 THEN result ...
- 转: ES6异步编程:Thunk函数的含义与用法
转: ES6异步编程:Thunk函数的含义与用法 参数的求值策略 Thunk函数早在上个世纪60年代就诞生了. 那时,编程语言刚刚起步,计算机学家还在研究,编译器怎么写比较好.一个争论的焦点是&quo ...
- 「python」: arp脚本的两种方法
「python」: arp脚本的两种方法 第一种是使用arping工具: #!/usr/bin/env python import subprocess import sys import re de ...
- JAVA代码静态检测之PMD
今天再次想启动Java代码静态检测工具的利用问题,主要再次尝试用了PMD,发现不少代码编码规范问题和好的代码建议,并学到不少自己之前没有注意到的Java方便的基础知识,感觉很不错,把相关明白的好的规则 ...
- net-ldap for ruby openNebula ldap
preface:ldap 主要概念及术语 OpenNebula issues:missing step to use LDAP as default driver cp -r /var/lib/one ...
- window.open打开新页面,并将本页数据用过url传递到打开的页面;需要两个页面;
页面1 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8 ...