概率dp+高斯消元解方程组-hdu-4326-Game
来源:互联网 发布:淘宝儿童男装春秋外套 编辑:程序博客网 时间:2024/05/22 01:33
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4326
题目大意:
有n个人,每次前面四个人玩游戏,每人赢得概率为1/4,四人中赢的人排在队首,输的人依次排到队尾。求第k个人连续赢m次的概率。
解题思路:
之前做过,每次博客,现在补上。
因为要考虑连续赢的情况并且每次动作只和第一个人有关,设第一维表示第一个人连续赢的次数。第二维表示第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[i][j]顺序作为x1,x2,x3,,,,,,,,,,,,,
( 0 1) (0 2)..(0,n)....(m-1,n)
(0 1)
(0 2)
....
(0,n)
....
(m-1,n)
代码:
#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<stack>#include<list>#include<queue>#define eps 1e-6#define INF 0x1f1f1f1f#define PI acos(-1.0)#define ll __int64#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1using namespace std;/*freopen("data.in","r",stdin);freopen("data.out","w",stdout);*/#define Maxn 120double g[Maxn][Maxn];double x[Maxn];int n,m,k;void add(int row,int i,int j,double v){ int col=i*n+j; if(i==m) { if(j==1) //p[i][j]=1; 为常数 g[row][m*n+1]+=-1.0*v; return ; } g[row][col]+=v; return ;}void gg(int r,int c) //高斯消元 求解方程组{ int row,col; for(row=1,col=1;row<r,col<c;row++,col++) { int t=row; for(int i=row+1;i<=r;i++) if(fabs(g[i][col])>fabs(g[t][col])) //找最大的主元 t=i; if(fabs(g[t][col])<eps) //说明这一列全部为零 continue; if(t-row) //不同则交换 { for(int i=col;i<=c;i++) swap(g[row][i],g[t][i]); } for(int i=row+1;i<=r;i++) { if(fabs(g[i][col])<eps) //已经是零了 continue; double tt=g[i][col]/g[row][col]; g[i][col]=0.0; //把后面的系数同一 for(int j=col+1;j<=c;j++) g[i][j]-=tt*g[row][j]; } } for(int i=r;i>=1;i--) //逆着往前求 { x[i]=g[i][c]; for(int j=r;j>i;j--) x[i]-=g[i][j]*x[j]; x[i]/=g[i][i]; } return ;}int main(){ int t; scanf("%d",&t); for(int ca=1;ca<=t;ca++) { memset(g,0,sizeof(g)); scanf("%d%d%d",&n,&m,&k); int row=0; for(int i=0;i<m;i++) //这里的i=0表示 for(int j=1;j<=n;j++) { row++; //表示每一个方程 第0行和第0列都没用 add(row,i,j,1.0); //加入到矩阵中 if(j==1) { add(row,i+1,j,-0.25); //移项后加入到矩阵中 add(row,1,n-2,-0.75); } else if(j==2) { add(row,i+1,n-2,-0.25); add(row,1,1,-0.25); add(row,1,n-1,-0.5); } else if(j==3) { add(row,i+1,n-1,-0.25); add(row,1,n-1,-0.25); add(row,1,1,-0.25); add(row,1,n,-0.25); } else if(j==4) { add(row,i+1,n,-0.25); add(row,1,n,-0.5); add(row,1,1,-0.25); } else { add(row,i+1,j-3,-0.25); add(row,1,j-3,-0.75); } } gg(row,n*m+1); //高斯消元求解m*n元方程 printf("Case #%d: %.6lf\n",ca,x[k]); } return 0;}
- 概率dp+高斯消元解方程组-hdu-4326-Game
- hdu - 4326 - Game - 概率dp
- HDU 4326 Game 概率DP 高斯消元
- HDU 4326 Game(概率DP+高斯消元)
- HDU 4326Game(比较难理解的概率dp)
- hdu3722Card Game 概率dp水题
- hdu 4870 Rating (高斯消元解概率dp)
- hdu football 概率DP
- hdu 3835 概率DP
- hdu 3853 概率DP
- hdu Robberies 概率DP
- hdu 4405 概率DP
- HDU 3853 概率DP
- hdu 4487 概率DP
- hdu 4089 概率dp
- HDU 3853 概率DP
- HDU 3853 概率dp
- hdu 4870(概率Dp)
- Apache Pig基础概念及用法
- WCF学习笔记
- 组队赛130827
- Keychain Group Access
- Inside Qt Series (四):对象数据存储(C)
- 概率dp+高斯消元解方程组-hdu-4326-Game
- volatile总结
- Linux 2.6 中的文件锁
- WTL设置edit中光标的位置
- 为svn添加 beyond conpaer作为 比较器
- 【discuz】discuz论坛系统中自定义广告位
- 网络传输中的字节序 大端小端
- java io文件学习笔记
- Java中enum和C#中的异同