洛谷1409骰子

题目描述
n个人排成一排,你排在第m个。每轮队首的人投一次骰子:
若掷到1,则队首的人获胜;
若掷到2,4,6,则队首的人出队;
若掷到3,5,则队首的人排到队尾。
获胜者仅有一人,若队列中仅剩一人,则该人获胜。求你获胜的概率。
输入输出格式
输入格式:
一行两个整数n,m
输出格式:
一个实数表示获胜概率(精确到小数点后9位)
输入输出样例
输入样例#1: 复制
2 1
输出样例#1: 复制
0.375000000
说明
【数据范围】
对于30%的数据:n<=10

对于100%的数据:n<=1000,m<=n

做了击倒概率题目后,做这个题目发现不会做。想了半天,花了个搜索树,做出了样例数据:0.375.

    1,2

1/6 :1赢     1/2 1输 :2      1/3: 2,1

                                                 1/6:2赢     1/2 1赢     1/3 :1,2

所以:f(1)=1/6+1/3 * 1/2+ 1/3 *1/3 *f(1)

=>f(1)=1/3  /   8/9=3/8=0.375.

但是已经ac的题目用的题目数据为:

若掷到1,则队首的人获胜;
若掷到2,4,6,则队首的人到队尾;

若掷到3,5,则队首的人出队。

画出的状态转移图为:


参考代码:

#include <iostream>
#include<cstdio> 
#include <cmath>
using namespace std;
double f[2000][2000];
int main()
{
    int n,m;
    cin>>n>>m;
    f[1][1]=double(1);
        for(int i=2;i<=n;++i){
        f[i][1]=1.0/6.0;
        for(int j=i-1;i-j<=60&&j>=1;--j){
        	f[i][1]+=f[i-1][j]/(1LL<<(i-j))/3;
        	// cout<<i-1<<"  "<<j<<"  "<<f[i][1]<<endl;
		}
       
        if(i<=60)f[i][1]/=((1LL<<i)-1)/(double)(1LL<<i);
       // cout<<f[i][1]<<endl;
        for(int j=2;j<=i;++j)
            f[i][j]=f[i-1][j-1]/3+f[i][j-1]/2;
    }
    printf("%0.9f",f[n][m]);
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/lengxuenong/article/details/80093699
今日推荐