• 【*游戏】


    我校最神的金牌爷安利给我的题

    金牌爷告诉我这道题水爆了

    天啊,金牌爷竟然给我安利题目啦

    刚开始看着黑色的标签感觉并不是很可做,但是看到金牌爷脖子上闪闪发光的金牌真挚的眼神

    我决定还是做一做

    于是就开开心心的做了一道水题

    我们设(dp[i][j])表示进行到(i)次游戏,这次游戏使用的是第(j)个骰子的概率

    首先我们先初始化,刚开始第一次游戏能用到的骰子跟(pi(i))有关系

    于是(dp[1][i]=pi(i)*a[i][O[1]])

    就是选择这个骰子并且能出现这次需要的点数的概率乘起来

    之后我们刷表转移

    对于一个(dp[i][j])我们使用完之后可能会换骰子于是我们就枚举下一个换的骰子(k),这个骰子需要出现对应的点数

    于是就有

    [dp[i+1][k]+=dp[i][j]*b[j][k]*a[k][O[i+1]] ]

    最后答案就是(sum_{i=1}^{n}dp[m][i])

    代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define re register
    #define maxn 1005
    #define eps 1e-6
    #define M 51
    double a[M][M],b[M][M];
    double pi[M],dp[maxn][maxn];
    int O[maxn];
    int n,m,Q;
    inline int check(double t,double k)
    {
    	if(t+eps>k&&t-eps<k) return 1;
    	return 0;
    }
    int main()
    {
    	scanf("%d%d%d",&n,&m,&Q);
    	for(re int i=1;i<=n;i++)
    		scanf("%lf",&pi[i]);
    	for(re int i=1;i<=n;i++)
    		for(re int j=0;j<Q;j++)
    			scanf("%lf",&a[i][j]);
    	for(re int i=1;i<=n;i++)
    		for(re int j=1;j<=n;j++)
    			scanf("%lf",&b[i][j]);
    	for(re int i=1;i<=m;i++)
    		scanf("%d",&O[i]);
    	for(re int i=1;i<=n;i++)
    		dp[1][i]=pi[i]*a[i][O[1]];
    	for(re int i=1;i<m;i++)
    		for(re int j=1;j<=n;j++)
    		{
    			if(check(dp[i][j],0)) continue;
    			for(re int k=1;k<=n;k++)
    				dp[i+1][k]+=dp[i][j]*a[k][O[i+1]]*b[j][k];
    		}
    	double ans=0;
    	for(re int i=1;i<=n;i++)
    		ans+=dp[m][i];
    	printf("%.4lf",ans);
    	return 0;
    }
    
  • 相关阅读:
    队列01--[队列&双端队列&循环队列&双端循环队列]
    LeetCode--[栈]--不定时更新
    栈01--[栈接口设计&&栈应用]
    初等数论初步
    成外国庆集训小记
    图论算法初步
    Are Lights Still On?
    二分答案和三分入门
    SCOI2010 传送带
    微信小程序 菜鸟笔记
  • 原文地址:https://www.cnblogs.com/asuldb/p/10206224.html
Copyright © 2020-2023  润新知