YunYan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
B. 掷骰子

单点时限: 2.0 sec

内存限制: 512 MB

骰子,中国传统民间娱乐用来投掷的博具,早在战国时期就已经被发明。

现在给你 n 个骰子,求 n 个骰子掷出点数之和为 a 的概率是多少。

输入格式

第一行输入一个整数 T,表示有 T 组测试数据1T10 
每组测试数据输入两个整数n,a,表示共有n个骰子,骰子点数总和为a(1n1000,na6n)

输出格式

如题。答案对 109+7 取余。

样例

input
2
1 2
2 2
output
166666668
27777778

一个状态转移方程dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;// i指的是第i个筛子,j指的是当点数为j的时候的总方案(看了好久都没看懂,先记下来吧)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=1e3+7;
ll dp[N][N*6];
ll arr[N];

ll ksm(ll x,ll y){
    ll res=1;
    while(y){
        if(y&1) res=res*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return res;
}

int main(){
    int t; 
    scanf("%d",&t);
    while(t--){ 
        int n,m;
        scanf("%d%d",&n,&m); 
        memset(dp,0,sizeof(dp));  
        dp[0][0]=1; 
        for(int i=1;i<=n;i++){
            for(int j=i;j<=6*n;j++){ 
                for(int k=j-6;k<j;k++){
                    if(k<0) continue;
                    dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;
                }
            }
        }
        printf("%lld\n",(dp[n][m]*ksm(ksm(6,n),mod-2))%mod);        
    } 
    return 0;
}

 




posted on 2019-08-18 22:58  Target--fly  阅读(228)  评论(0编辑  收藏  举报