【tyvj P4879】骰子游戏

http://www.tyvj.cn/p/4879

首先,投一个骰子,每个数字出现的概率都是一样的。也就是不算小A的话,n个人投出x个骰子需要的次数和点数无关。

计数问题考虑dp,令f(i,j)为前i个人投j个同点数的骰子的方案数,容易得f(i,j)=sum{f(i-1,j-k)*f(1,k) | 0<=k<=m}.

边界是f(1,j),具体是什么值呢?一个人投m个骰子,会得到6种点数,其中一种有j个,其他的五种有m-j个。也就是把m-j个骰子分成5份的方案数。

用插板法可得f(1,j)=C(m-j+4,4)=(m-j+1)(m-j+2)(m-j+3)(m-j+4)/24.

然后好像说这玩意可以用FFT优化,真成NOI Plus模拟赛了……

#include <iostream>
#define maxn 405
using namespace std;
typedef unsigned long long ullint;
const ullint c=998244353;
int n,m,x,y;
ullint dp[maxn][maxn*maxn];
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m>>x>>y;
    int cnt=0,tmp;
    for(int i=1;i<=m;i++)
    {
        cin>>tmp;
        if(tmp==y)
            cnt++;
    }

    for(int j=0;j<=m;j++)
        dp[1][j]=(m-j+1)%c*(m-j+2)%c*(m-j+3)%c*(m-j+4)%c*291154603%c;
    for(int i=2;i<=n;i++)
        for(int j=0;j<=i*m;j++)
            for(int k=0;k<=min(j,m);k++)
                dp[i][j]=(dp[i][j]+dp[i-1][j-k]*dp[1][k]%c)%c;
    ullint ans=0;
    for(int j=x-cnt;j<=n*m;j++)
        ans=(ans+dp[n][j])%c;
    cout<<ans<<endl;
    return 0;
}
时间: 2024-10-04 19:38:21

【tyvj P4879】骰子游戏的相关文章

华为历年试题(掷骰子游戏 7)

问题描述: 在掷骰子游戏中,会根据所掷数字在地图中前进几步,前进完成后需要根据当前地图位置所示的障碍进行相应操作,其中障碍表示: 1)  9:无障碍 2)  1:停掷一轮,即下轮所掷数字无效: 3)  2:后退两步,如果已经到起点不再后退: 4)  3:奖励前进一步 如果在游戏过程中,已经走到地图终点,则游戏结束.根据输入的地图数组,和5个骰子数的数组,返回最终玩家前进了多少步. 要求实现函数: void dice(int map_len, int* map, int* dice_val, in

模拟算法_掷骰子游戏&amp;&amp;猜数游戏

模拟算法是用随机函数来模拟自然界中发生的不可预测的情况,C语言中是用srand()和rand()函数来生成随机数. 先来介绍一下随机数的生成: 1.产生不定范围的随机数 函数原型:int rand() 产生一个介于0~RAD_MAX间的整数,其具体值与系统有关系.Linux下为2147483647.我们可以在include文件夹中的stdlib.h中可以看到(Linux在usr目录下,Windows在安装目录下) 1 #include<stdio.h> 2 #include<stdlib

【Java自学】掷骰子游戏

1 package codeTask_FangFa; 2 /*5.29 掷骰子游戏. 规则: 3 扔两个骰子,计算和. 2.3或12(称作掷骰子)你就输了,7或11(称作自然),你就赢了.如果是其他数字. 4 继续掷,直到出来一个7(你输了)或者出来一个和刚才一样的(你赢了). 5 */ 6 7 import java.util.Random; 8 public class ZhiTouZi { 9 public static void main(String[] args){ 10 11 Sy

华为机试—掷骰子游戏

在掷骰子游戏中,会根据所掷数字在地图中前进几步,前进完成后需要根据当前地图位置所示的障碍进行相应操作,其中障碍表示: 1)9:无障碍 2)1:停掷一轮,即下轮所掷数字无效: 3)2:后退两步,如果已经到起点不再后退: 4)3:奖励前进一步 如果在游戏过程中,已经走到地图终点,则游戏结束.根据输入的地图数组,和5个骰子数的数组,返回最终玩家前进了多少步. 示例 1)输入:map_len = 15, map = {9,1,9,9,9,2,9,9,9,9,9,9,9,9,9},dice_val = {

【整理】HTML5游戏开发学习笔记(1)-骰子游戏

<HTML5游戏开发>,该书出版于2011年,似乎有些老,可对于我这样没有开发过游戏的人来说,却比较有吸引力,选择自己感兴趣的方向来学习html5,css3,相信会事半功倍.不过值得注意的是,该书的游戏是些小的游戏,内容相对比较基础,而且html5标准已经正式发布,可能会和书中所描述有少许出处.当然了,书中的小游戏还是比较不错的,适合我这样的前端开发不咋地的来练手,学习方式是在以自己的思路实现之后,再来看书中的实现思路,因为每个人有自己的开发习惯. 1.预备知识在做第一个骰子游戏开发前,必须知

09骰子游戏

骰子游戏 我们来玩一个游戏.同时掷出3个普通骰子(6个面上的数字分别是1~6).如果其中一个骰子上的数字等于另外两个的和,你就赢了. 下面的程序计算出你能获胜的精确概率(以既约分数表示) public class Main{public static int gcd(int a, int b){if(b==0) return a;return gcd(b,a%b);} public static void main(String[] args){ int n = 0;for(int i=0; i

掷骰子游戏和条件语句

1.java掷骰子游戏 public class iftest { public static void main(String[] args) { System.out.println("#####掷骰子游戏#####"); System.out.println("#################"); //投掷三个色子看看今天手气怎么样? int i = (int)(6*Math.random()+1); int j = (int)(6*Math.random

掷骰子游戏窗体实现--Java初级小项目

掷骰子 **多线程&&观察者模式 题目要求:<掷骰子>窗体小游戏,在该游戏中,玩家初始拥有1000的金钱,每次输入押大还是押小,以及下注金额,随机3个骰子的点数,如果3个骰子的总点数小于等于9,则开小,否则开大,然后判断玩家是否押对,如果未押对则扣除下注金额,如果押对则奖励和玩家下注金额相同的金钱. 分析:这个题目要求灵活运用多线程的相关知识,达到点击开始按钮时,有3个线程启动,分别控制3颗骰子的转动,在3颗骰子全部转完以后,回到主线程计算游戏结果. 1 //3个线程控制3颗骰

重温C++---骰子游戏---ShinePans

//this is a program witch played by two people //二人游戏,若第一个抛骰子,抛两次的和为7或11则第一人直接胜利,第二人直接失败 //若第一个人抛骰子,抛两次的和为2,3或12,则第一个人直接失败,第二人胜利 //若第一个人抛筛子,抛两次的和以上均不是,则由第二个人抛,直到有一方胜利 #include <iostream> #include <stdlib.h> #include <ctime> //获取系统时间的头文件