小A买彩票

链接:https://ac.nowcoder.com/acm/contest/549/C
来源:牛客网

小A最近开始沉迷买彩票,并且希望能够通过买彩票发家致富。已知购买一张彩票需要3元,而彩票中奖的金额分别为1,2,3,4元,并且比较独特的是这个彩票中奖的各种金额都是等可能的。现在小A连续购买了n张彩票,他希望你能够告诉他至少能够不亏本的概率是多少。

输入描述:

一行一个整数N,为小A购买的彩票数量一行一个整数N,为小A购买的彩票数量NA

输出描述:

输出一个最简分数a/b,表示小A不亏本的概率。若概率为1,则输出1/1,概率为0,则输出0/1。输出一个最简分数a/b,表示小A不亏本的概率。 \\若概率为1,则输出1/1,概率为0,则输出0/1。a/bA11/100/1
示例1

输入

复制
2

输出

复制
3/8

备注:

0≤n≤300

dp[i][j]表示前i张彩票中奖j元的方案数
那么易得转移方程
dp[i][j] += dp[i-1][j-k] 其中1≤k≤4 k≤j
边界为dp[0][0]
买n张彩票,每张彩票有四种情况,总的方案数就是sum=4^n
所以计算出来ans=sum(dp[n][k]) 其中k>=3n
答案就是ans/sum

就是注意0的时候是1/1

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=40;
const int maxx=1e4+100;
ll dp[maxn][maxx];//dp[i][j]代表的是前i张彩票赚j块钱的数量 
ll qpow(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1){
            ans=ans*a;
        } 
        a=a*a;
        b/=2;
    }
    return ans;
}
int n;
int main(){
    cin>>n;
    dp[1][1]=1;
    dp[1][2]=1;
    dp[1][3]=1;
    dp[1][4]=1; 
    for(int i=2;i<=n;i++){
        for(int j=1;j<=4*n;j++){
            if(j>=1){
                dp[i][j]+=dp[i-1][j-1];
            }
            if(j>=2){
                dp[i][j]+=dp[i-1][j-2];
            }
            if(j>=3){
                dp[i][j]+=dp[i-1][j-3];
            }
            if(j>=4){
                dp[i][j]+=dp[i-1][j-4];
            }
        }
    } 
    ll ans=0;
    for(int i=3*n;i<=4*n;i++){
        ans+=dp[n][i];
    }
    ll sum=qpow(4,n);
    ll d=__gcd(ans,sum);
    if(n==0){
        cout<<1<<"/"<<1<<endl;
    }
    else
        printf("%lld/%lld\n",ans/d,sum/d); 
} 

 

posted @ 2021-01-25 18:18  lipu123  阅读(82)  评论(0编辑  收藏  举报