P1409 骰子

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;
}
posted @ 2022-09-05 11:37  艾特玖  阅读(79)  评论(0)    收藏  举报