NC23413 小A买彩票(背包DP)

题目链接

题意:
小 A 买 彩 票 , 每 张 彩 票 3 元 小A买彩票,每张彩票3元 A3
可 以 中 奖 1 , 2 , 3 , 4 元 , 概 率 相 同 可以中奖1,2,3,4元,概率相同 1234
问 买 n 张 彩 票 不 亏 的 概 率 问买n张彩票不亏的概率 n
题解:
n < = 30 n<=30 n<=30
题 目 要 求 输 出 分 子 分 母 的 最 简 形 式 题目要求输出分子分母的最简形式
所 以 就 是 求 , 买 n 张 彩 票 的 所 有 情 况 , 和 不 亏 的 情 况 所以就是求,买n张彩票的所有情况,和不亏的情况 n
两 个 分 别 为 分 母 分 子 , 进 行 g c d 输 出 即 可 两个分别为分母分子,进行gcd输出即可 gcd

所 以 只 要 计 算 的 是 不 亏 的 情 况 , 那 么 就 是 n 张 彩 票 最 后 得 到 3 ∗ n 以 上 的 情 况 所以只要计算的是不亏的情况,那么就是n张彩票最后得到3*n以上的情况 n3n
这 个 n 相 当 小 , 直 接 用 背 包 记 录 3 ∗ n 以 上 有 几 种 情 况 这个n相当小,直接用背包记录3*n以上有几种情况 n3n
因 为 彩 票 最 多 能 中 的 情 况 为 全 部 是 4 元 , 即 是 4 ∗ n 因为彩票最多能中的情况为全部是4元,即是4*n 44n
所 以 再 这 个 区 间 里 的 方 案 数 都 是 符 合 的 所以再这个区间里的方案数都是符合的
然 后 进 行 背 包 转 移 然后进行背包转移
d p [ i ] [ j ] 表 示 前 i 张 彩 票 中 了 j 元 的 方 案 数 dp[i][j]表示前i张彩票中了j元的方案数 dp[i][j]ij
d p [ i ] [ j ] = ∑ d p [ i − 1 ] [ j − k ] dp[i][j]=\sum{dp[i-1][j-k]} dp[i][j]=dp[i1][jk]
对 每 种 彩 票 进 行 枚 举 , 彩 票 的 面 值 为 k 对每种彩票进行枚举,彩票的面值为k k
最 后 ∑ 3 ∗ n 4 ∗ n d p [ n ] [ i ] 最后\sum_{3*n}^{4*n}{dp[n][i]} 3n4ndp[n][i]就是分子
分 母 就 是 4 的 n 次 方 , 每 次 有 4 种 选 择 分母就是4的n次方,每次有4种选择 4n4
两 者 g c d 相 除 输 出 即 可 两者gcd相除输出即可 gcd
AC代码

/*
    Author:zzugzx
    Lang:C++
    Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
#define SZ(x) (int)x.size()
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double,double> pdd;
const int mod=1e9+7;
//const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[8][2]={{0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};

ll dp[50][200];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    ll n;
    cin>>n;
    ll N=4*n;
    dp[0][0]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=4;j++)
            for(int k=N;k>=j;k--)
                dp[i][k]+=dp[i-1][k-j];
    ll ans=0;
    for(int i=3*n;i<=N;i++)ans+=dp[n][i];
    N=1ll<<(2*n);
    ll x=__gcd(ans,N);
    cout<<ans/x<<'/'<<N/x<<endl;
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值