牛客小白赛13 C-买彩票

本文介绍了一种通过动态规划算法解决彩票购买盈亏概率的问题,详细解析了如何使用状态转移方程来计算连续购买n张彩票至少不亏本的概率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

输入描述:

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

输出描述:

 

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

示例1

输入

2

输出

3/8

备注:

0≤n≤30

一开始看到这种求概率的题,我都是傻傻的推公式,也不是不能推,只是会比较麻烦,而且不能被条件搞混淆,我推不出来。

不过大部分人用的办法都是找前后两项的关系。

也就是思考买i张彩票不亏本的概率,与买i-1张彩票不亏本的概率是否有关系。

很明显的是,有关系的。假设目前已经买了3张彩票,我现在要买第四张。

第四张购买赚钱有四种情况(每张都有的四种情况) -2元  -1元   0元  1元

例如,如果第四张买了个 -2元(中奖1元),那么这种情况下想要不亏,就必须前面三张要至少赚 2 元。

同理,买了-1元,前面三张必须至少赚 1 元。

这也就说明,后面购买的盈亏情况可以直接有前面几张的情况得到,状态转移方程如下:

dp[i][j]  代表第 i 张彩票赚了 j 元的可能情况数。

dp[i][j]=dp[i-1][j-1]+dp[i-1][j]+dp[i-1][j+1]+dp[i-1][j+2]

输入的数字为n 只需要记录第n层所有不亏的种类数。代码如下

#include<stdio.h>
#include<iostream>
 
using namespace std;
 
typedef unsigned long long ll;
 
ll dp[35][200]={0};
 
ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}
 
 
 
int main(){
    int n;
    cin>>n;
     
    const int ze=100;      //定义一个0点,小于0点的位置说明亏损。
    dp[0][ze]=1;
    dp[1][ze]=1;
    dp[1][ze-1]=1;
    dp[1][ze-2]=1;
    dp[1][ze+1]=1;
    int i,j;
    for(i=2;i<=n;i++)
        for(j=ze-(n*2);j<=ze+n;j++){
            for(int k=j-1;k<=j+2;k++)
                dp[i][j]=dp[i][j]+dp[i-1][k];
        }  
     
    ll sum=0;
    for(i=ze;i<=ze+n;i++)
        sum=sum+dp[n][i];
     
    ll s2=ll(1<<n)*ll(1<<n);            // s2代表分母,这里是4^n
    ll g=gcd(sum,s2);
    printf("%lld/%lld\n",sum/g,s2/g);
     
     
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值