筛子游戏(概率DP) 牛客

题目在这里

题目大意:
有三个面数给定的骰子,每次投出前进x+y+z(三个骰子投出的数字),开始位置在0点,问位置>n的期望步数?
特别的,如果xa&&yb&&z==c会回到0点

分析:
设f[i]表示分数到达i的期望步数
f [ i ] = ∑ ( p k ∗ f [ i + k ] ) + p 0 ∗ f [ 0 ] + 1 f[i]=\sum(pk*f[i+k])+p0*f[0]+1 f[i]=(pkf[i+k])+p0f[0]+1
但是f[0]是一个未知数,所以需要使用一种常见手法进行转化。
f [ i ] = A [ i ] ∗ f [ 0 ] + B [ i ] f[i]=A[i]*f[0]+B[i] f[i]=A[i]f[0]+B[i]
带入方程右边
f [ i ] = ∑ ( p k ∗ A [ i + k ] ∗ f [ 0 ] + p k ∗ B [ i + k ] ) + p 0 ∗ f [ 0 ] + 1 f[i]=\sum(pk*A[i+k]*f[0]+pk*B[i+k])+p0*f[0]+1 f[i]=(pkA[i+k]f[0]+pkB[i+k])+p0f[0]+1
= ( ∑ ( p k ∗ A [ i + k ] ) + p 0 ) ∗ f 0 + ∑ ( p k ∗ B [ i + k ] ) + 1 =(\sum(pk*A[i+k])+p0)*f0+\sum(pk*B[i+k])+1 =((pkA[i+k])+p0)f0+(pkB[i+k])+1
得到
A [ i ] = ∑ ( p k ∗ A [ i + k ] ) + p 0 A[i]=\sum(pk*A[i+k])+p0 A[i]=(pkA[i+k])+p0
B [ i ] = ∑ ( p k ∗ B [ i + k ] ) + 1 B[i]=\sum(pk*B[i+k])+1 B[i]=(pkB[i+k])+1

已知:
A [ n ] = 0 A[n]=0 A[n]=0
B [ n ] = 0 B[n]=0 B[n]=0

可以递推求解A[0]和B[0]
最后得到f[0]

f [ 0 ] = B [ 0 ] / ( 1 − A [ 0 ] ) f[0]=B[0]/(1-A[0]) f[0]=B[0]/(1A[0])

#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
using i128 = __int128;
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

double n,a,b,c,k1,k2,k3,p0;
double p[1024],A[1024],B[1024];

int main(){
    ios;
    cin>>n>>k1>>k2>>k3>>a>>b>>c;
    p0 = 1.0/k1/k2/k3;
    for(int i = n;i>=0;--i){
        for(int x = 1;x<=k1;++x){
            for(int y = 1;y<=k2;++y){
                for(int z = 1;z<=k3;++z){
                    if(x==a&&y==b&&z==c) continue;
                    int k = x+y+z;
                    A[i] += p0*A[i+k];
                    B[i] += p0*B[i+k];
                }
            }
        }
        A[i]+=p0;
        B[i]+=1.0;
    }
    double ans = B[0]/(1.0-A[0]);
    cout<<fixed<<setprecision(10)<<ans<<'\n';
    return 0;
}

好想学会DP

  • 22
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值