hdu - 4326 - Game - 概率dp

本題題意很簡單,給出n個人每次4人進行比賽其他人等待,勝者繼續,負者排到最後,連續或得m次勝利的人成爲最終的贏家,求第k個人最終獲得勝利的概率是多少?

對於這題,我們首先確立一個這樣的模型: x1先贏了i局,正在於x2,x3,x4賭鬥,後面依次有x5,x6,……,xn等待。用P[i][j]表示x1先贏了i局的情況下,當前的xj獲勝的概率。

http://acm.hdu.edu.cn/showproblem.php?pid=4326
i < m

P[i][j] = P[i + 1][j] * 1/4 + P[1][n - 2] * 3/4 j = 1

P[i + 1][n - 2] * 1/4 + P[1][1] * 1/4 + P[1][n - 1] * 2/4 j = 2

P[i + 1][n - 1] * 1/4 + P[1][1] * 1/4 + P[1][n - 1] * 1/4 + P[1][n] * 1/4 j = 3

P[i + 1][n] * 1/4 + P[1][1] * 1/4 + P[1][n] * 2/4 j = 4

P[i + 1][j - 3] * 1/4 + P[1][j - 3] * 3/4 j >=4

i = m

P[i][j] = 1 j = 1

0 j != 1

運用分數形式的高斯消元解方程。

#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)    g[cnt][n*m+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]);
        }
        if(fabs(g[row][col])<eps)   continue;
        for(i=row+1;i<=n;i++){
            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++)
            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(n*m,n*m+1);
        printf("Case #%d: %.6lf\n",++nn,x[k]);
    }
    return 0;
}


發佈了177 篇原創文章 · 獲贊 2 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章