首页 > 其他分享 >P1409 骰子

P1409 骰子

时间:2022-09-05 11:44:36浏览次数:87  
标签:骰子 P1409 int 队首 ios 获胜

P1409 骰子

题目大意

\(n\) 个人排成一排,你排在第 \(m\) 个。

每轮队首的人投一次骰子。

  • 若掷到 \(1\),则队首的人获胜。
  • 若掷到 \(2,4,6\),则队首的人排到队尾。
  • 若掷到 \(3,5\),则队首的人出队。

若队列中仅剩一人,则该人获胜,求你获胜的概率。

分析

考虑到DP倒是不难,但是我们推的时候会发现,状态相互依赖了,不是一个DAG。

我们来推导一下式子。

假设我们求得是f[n][x]

x>=1, 则f[n][x] = f[n][x-1]*(1/2) + (1/3)*f[n-1][x-1]

x==1,则f[n][1] = f[n][n]*(1/2) + 1/6

但此时,我们可以注意一下其正好构成一个循环。

我们可以循环带入解方程,算出f[n][n],再求出f[n][1],接下来再递推f[n][x](x>1)

Ac_code

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false); cin.tie(0), cout.tie(0)
using namespace std;

const int N = 1010;

double f[N][N];

int main()
{
    ios;
    int n,m;
    cin>>n>>m;
    f[1][1] = 1;
    for(int i=2;i<=n;i++)
    {
        double a = 1.0/2,b = 1.0/6;
        for(int j=2;j<=i;j++)
        {
            a/=2;
            b = b/2 + f[i-1][j-1]/3;
        }
        f[i][i] = b/(1-a);
        f[i][1] = f[i][i]/2 + 1.0/6;
        for(int j=2;j<=i;j++)
        {
            f[i][j] = f[i][j-1]/2 + f[i-1][j-1]/3;
        }
    }
    cout<<fixed<<setprecision(9)<<f[n][m]<<'\n';
    return 0;
}

标签:骰子,P1409,int,队首,ios,获胜
From: https://www.cnblogs.com/aitejiu/p/16657561.html

相关文章

  • 扔骰子期望
    扔骰子可以选择扔到某个数的时候获得然后退出或者不拿走继续扔dp[i]表示扔第i次的时候的最大期望f[n]=1/6*(max(1,f(n-1))+max(2,f(n-2))+max(3,f(n-1))+max(4,f(n-......