【AcWing】蓝桥杯集训每日一题Day29|数学期望|DP|4009.收集卡牌(C++)

4009.收集卡牌
4009. 收集卡牌 - AcWing题库
难度:困难
时/空限制:1s / 512MB
总通过数:995
总尝试数:1852
来源:

第23次CCF计算机软件能力认证
算法标签

数学期望DP状态压缩DP记忆化搜索

题目内容

小林在玩一个抽卡游戏,其中有 n 种不同的卡牌,编号为 1 到 n。
每一次抽卡,她获得第 i 种卡牌的概率为 pi。
如果这张卡牌之前已经获得过了,就会转化为一枚硬币。
可以用 k 枚硬币交换一张没有获得过的卡。
小林会一直抽卡,直至集齐了所有种类的卡牌为止,求她的期望抽卡次数。
如果你给出的答案与标准答案的绝对误差不超过  1 0 − 4 10^{-4} 104,则视为正确。
提示:聪明的小林会把硬币攒在手里,等到通过兑换就可以获得剩余所有卡牌时,一次性兑换并停止抽卡。

输入格式

输入共两行。
第一行包含两个用空格分隔的正整数 n,k,第二行给出 p1,p2,…,pn,用空格分隔。

输出格式

输出共一行,一个实数,即期望抽卡次数。

数据范围

对于 20% 的数据,保证 1≤n,k≤5。
对于另外 20% 的数据,保证所有 pi 是相等的。
对于 100% 的数据,保证 1≤n≤16,1≤k≤5,所有的 pi 满足 pi≥1/10000,且  ∑ i = 1 n \sum_{i=1}^n i=1n pi=1。
注意,本题在官网必须保留 10 位小数才能通过(可能是没加SPJ),在本网站无此问题,只要满足你给出的答案与标准答案的绝对误差不超过  1 0 − 4 10^{-4} 104,则视为正确。

输入样例1:
2 2
0.4 0.6
输出样例1:
2.52
样例1解释

共有 2 种卡牌,不妨记为 A 和 B,获得概率分别为 0.4 和 0.6,2 枚硬币可以换一张卡牌。下面给出各种可能出现的情况:

  • 第一次抽卡获得 A,第二次抽卡获得 B,抽卡结束,概率为 0.4×0.6=0.24,抽卡次数为 2。
  • 第一次抽卡获得 A,第二次抽卡获得 A,第三次抽卡获得 B,抽卡结束,概率为 0.4×0.4×0.6=0.096,抽卡次数为 3。
  • 第一次抽卡获得 A,第二次抽卡获得 A,第三次抽卡获得 A,用硬币兑换 B,抽卡结束,概率为 0.4×0.4×0.4=0.064,抽卡次数为 3。
  • 第一次抽卡获得 B,第二次抽卡获得 A,抽卡结束,概率为 0.6×0.4=0.24,抽卡次数为 2。
  • 第一次抽卡获得 B,第二次抽卡获得 B,第三次抽卡获得 A,抽卡结束,概率为 0.6×0.6×0.4=0.144,抽卡次数为 3。
  • 第一次抽卡获得 B,第二次抽卡获得 B,第三次抽卡获得 B,用硬币兑换 A,抽卡结束,概率为 0.6×0.6×0.6=0.216,抽卡次数为 3。

因此答案是 0.24×2+0.096×3+0.064×3+0.24×2+0.144×3+0.216×3=2.52

输入样例2:
4 3
0.006 0.1 0.2 0.694
输出样例2:
7.3229920752
题目解析

最后用硬币兑换没有出现过的卡牌

n表示卡牌总共的种类
k表示多少枚硬币换一张卡牌

第二行是每次抽到每张卡牌的概率

输出期望抽卡次数

非常经典的,在算法题里常见的数学期望问题‘

从数学期望的角度分析

n很小,表示状态的时候需要用状态压缩的思想

如何表示状态

假设n=5,现在的卡牌有2,4,5,硬币的数量是2
因为n很小,只有16,表示有哪些卡牌的时候,可以用一个压缩的状态,用一个5位的01串来表示,01011,分别表示这5张卡牌有没有
用第二个数表示硬币数
所以状态可以用 ( 01011 , 2 ) (01011,2) (01011,2)的二维状态来表示
写代码的时候把01串看成是二进制表示,转化成对应的十进制数来存储

从当前这个状态直到集齐所有卡牌,这个过程在概率论里面称为事件

需要找一下不同事件之间的关系

比如 ( 01011 , 2 ) (01011,2) (01011,2),可以转化成哪些事件呢
就看下一抽能抽到什么卡牌
一共有五种抽发,所以能变成五种事件,概率分别是 p 1 , p 2 , p 3 , p 4 , p 5 p_{1},p_{2},p_{3},p_{4},p_{5} p1,p2,p3,p4,p5
如果下一抽抽的是第一张卡牌的话,变成的事件分别是 X 1 , X 2 , X 3 , X 4 , X 5 X_{1},X_{2},X_{3},X_{4},X_{5} X1X2,X3,X4,X5
X 1 X_{1} X1 ( 11011 , 2 ) (11011,2) (11011,2)
X 2 X_{2} X2 ( 01011 , 3 ) (01011,3) (01011,3)
X 3 X_{3} X3 ( 01111 , 2 ) (01111,2) (01111,2)
X 4 X_{4} X4 ( 01011 , 3 ) (01011,3) (01011,3)
X 5 X_{5} X5 ( 01011 , 3 ) (01011,3) (01011,3)
设初始事件是 X X X,会被5种不同的概率分辨成5种事件
当然在变成 X 1 X_{1} X1的时候,需要付出1抽的代价
所以期望是加1的,因为要多一步

这几个事件之间的关系

X = P 1 ( X 1 + 1 ) + ⋯ + P n ( X n + 1 ) X=P_{1}(X_{1}+1)+\dots+P_{n}(X_{n}+1) X=P1(X1+1)++Pn(Xn+1)
E ( x ) = E ( P 1 ( X 1 + 1 ) + ⋯ + P n ( X n + 1 ) ) E(x)=E(P_{1}(X_{1}+1)+\dots+P_{n}(X_{n}+1)) E(x)=E(P1(X1+1)++Pn(Xn+1))
要找的是 E ( x 1 ) E(x_{1}) E(x1) E ( x 2 ) E(x_{2}) E(x2)一直到 E ( x 5 ) E(x_{5}) E(x5)之间的关系
但是 E ( x ) E(x) E(x)里面还有其他的项,又有乘法又有加法
要用期望的运算性质把它展开整理一下

期望的运算性质
E ( C ) = C E ( C X ) = C E ( x ) E ( X + Y ) = E ( x ) + E ( Y ) \begin{array}{} E(C)=C \\ E(CX)=CE(x) \\ E(X+Y)=E(x)+E(Y) \end{array} E(C)=CE(CX)=CE(x)E(X+Y)=E(x)+E(Y)
E ( x ) = E ( P 1 ( X 1 + 1 ) ) + ⋯ + E ( P n ( X n + 1 ) = P 1 E ( X 1 + 1 ) + ⋯ + P n E ( X n + 1 ) \begin{array}{} E(x)=E(P_{1}(X_{1}+1))+\dots+E(P_{n}(X_{n}+1) \\ =P_{1}E(X_{1}+1)+\dots+P_{n}E(X_{n}+1) \end{array} E(x)=E(P1(X1+1))++E(Pn(Xn+1)=P1E(X1+1)++PnE(Xn+1)
x可以看成一个随机变量,相当于这个事件发生的概率是100%
= P 1 ( E ( X 1 ) + E ( 1 ) ) + ⋯ + P n ( E ( X n ) + E ( 1 ) ) = P 1 ( E ( X 1 ) + 1 ) + ⋯ + P n ( E ( X n ) + 1 ) \begin{array}{} =P_{1}(E(X_{1})+E(1))+\dots+P_{n}(E(X_{n})+E(1)) \\ =P_{1}(E(X_{1})+1)+\dots+P_{n}(E(X_{n})+1) \end{array} =P1(E(X1)+E(1))++Pn(E(Xn)+E(1))=P1(E(X1)+1)++Pn(E(Xn)+1)

写代码的时候就和DP差不多了
f ( s , c ) = p 1 ( f ( s 1 , c 1 ) + 1 ) + ⋯ + p n ( f ( s n , c n ) + 1 ) f(s,c)=p_{1}(f(s_{1},c_{1})+1)+\dots+p_{n}(f(s_{n},c_{n})+1) f(s,c)=p1(f(s1,c1)+1)++pn(f(sn,cn)+1)
可以看成一个DP问题

状态数量

第一维有16位,每一位有2种取法,2^16
第二维最多是每5个硬币换一张卡牌,所以k不可能大于80
因为如果有80个硬币,就可以换所有卡牌
一共是500多万个状态

每次算每个状态的时候,右边会有n项,8000万的计算量
而且有的状态是没有意义的,达不到的

用记忆化搜索来写
可以搜不到用不到的状态


数学期望是用DP来存的,期望的定义和DP是差不多的
如果不了解数学期望,可以把一个随机变量看成是一个集合
接下来就从集合角度分析DP问题

每一个事件可以看成一个集合
从当前状态集完所有卡牌的事件可以看成一个集合
抽五次的概率,p1
抽六次的概率,p2

左边一列是抽取的次数,右边一列是对应的概率
可以把这个集合看成是随机变量

代码
#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;const int N = 16, M = 1 << N;
//M表示每一种卡牌手里有没有int n, m;
//p表示每种卡牌抽到的概率,f表示状态
double p[N], f[M][N * 5 + 1];double dp(int state, int coins, int r)
{//用v来表示当前状态double& v = f[state][coins];//如果v大于等于0,表示这个状态算过了if (v >= 0) return v;//否则判断一下当前缺少的卡牌数量//如果硬币能够兑换剩下的,返回,不需要再抽了if (coins >= r * m) return v = 0;//否则计算当前状态v = 0;for (int i = 0; i < n; i ++)//如果当前状态已经有这种卡牌了if (state >> i & 1)v += p[i] * (dp(state, coins + 1, r) + 1);else//如果没有这种卡牌的话,获得这张卡牌v += p[i] * (dp(state | (1 << i), coins, r-1) + 1);//多了一种没有用的卡牌,缺的卡牌数量应该减1return v;
}int main()
{scanf("%d%d", &n, &m);//读入每种卡牌抽到的概率for (int i = 0; i < n; i ++) scanf("%lf", &p[i]);//先将所有状态初始化成-1memset(f, -1, sizeof f);//输出一下一张卡牌也没有,硬币也是0的状态printf("%.10lf\n", dp(0, 0, n));//n表示一开始state有n位是0return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/813081.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

淘宝/天猫获得淘宝商品评论 API 返回值说明,item_review-获得淘宝商品评论

淘宝/天猫的API通常不对公众开放&#xff0c;特别是涉及到具体商品评论的API。商家或开发者需要使用淘宝/天猫开放平台提供的API进行开发&#xff0c;并且需要遵循一定的申请流程和权限限制。 对于“item_review-获得淘宝商品评论”的API返回值说明&#xff0c;我无法提供具体…

CSS3 立体 3D 变换

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 ✍CSS3 立体 3D 变换&#x1f48e;1 坐标轴&#x1f48e;2 perspective 透视视…

mybatis-puls-配置日志

#日志配置 mybatis-plus.configuration.log-implorg.apache.ibatis.logging.stdout.StdOutImpl 我们所有的sql现在是不可见的&#xff0c;我们希望知道它是怎么执行的&#xff0c;所以我们必须要看日志

远程连接工具NoMachine的使用

一、软件介绍 NoMachine是一款远程桌面软件。适用于Linux、windows、ARM、Android等几乎全系统。常见的远程桌面软件还有向日葵、ToDesk等。选择NoMachine是因为它支持ARM32位、ARM64位处理器。 ZeroTier是一款内网穿透软件&#xff0c;通过建立虚拟局域网&#xff0c;能够实现…

springboot 整合 websocket

添加 websocket 依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>启用Springboot对WebSocket的支持package com.vazquez.k8sclient.config;import org.…

校园通用型发生网络安全事件解决方案

已知校园多教学楼、多教学机房、非标网络机房缺乏防护设备、检测设备、安全保护软件(杀软) 切断所有外网&#xff0c;断网处理!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 部署路由系统可选择爱快、routeros、openwrt。等。可将日志上传到日志分析系统。《这项非必要的》 部署开源防火…

电商用户行为数据分析

本文针对淘宝app的运营数据&#xff0c;以行业常见指标对用户行为进行分析&#xff0c;包括UV、PV、新增用户分析、漏斗流失分析、留存分析、用户价值分析、复购分析等内容。本文使用的分析工具以MySQL为主&#xff0c;涉及分组汇总&#xff0c;引用变量&#xff0c;视图&#…

视频评论ID提取工具|视频关键词评论批量采集软件

视频评论ID提取工具&#xff1a;批量抓取视频评论 视频评论ID提取工具是一款功能强大的软件&#xff0c;可以帮助您批量抓取视频视频下的评论信息。通过输入关键词和评论监控词&#xff0c;即可进行评论的抓取&#xff0c;并提供评论昵称、评论日期、评论内容、命中关键词以及所…

内存分页分段

前言 在段式内存中&#xff0c;当申请内存的时候就划分一块内存给它&#xff0c;假如一个空间有4096MB大小内存&#xff0c;实际使用了3000MB&#xff0c;假如想运行一个程序是1024MB大小的看起来是能满足&#xff0c;但是数据段或者代码段对于内存的要求必须是连续了&#xf…

【Java面试题】JVM(26道)

文章目录 JVM面试题基础1.什么是JVM&#xff1f;2.JVM的组织架构&#xff1f; 内存管理3.JVM的内存区域是什么&#xff1f;3.1堆3.2方法区3.3程序计数器3.4Java虚拟机栈3.5本地方法栈 4.堆和栈的区别是什么&#xff1f;5.JDK1.6、1.7、1.8内存区域的变化&#xff1f;6.内存泄露…

Python学习入门(1)——基础语句(二)

14. 迭代器和迭代协议 在Python中&#xff0c;迭代器是支持迭代操作的对象&#xff0c;即它们可以一次返回其成员中的一个。任何实现了 __iter__() 和 __next__() 方法的对象都是迭代器。 class Count:def __init__(self, low, high):self.current lowself.high highdef __i…

tailwindcss在manoca在线编辑智能感知

推荐一下monaco-tailwindcss库&#xff0c;它实现在monaco-editor网页在线编辑器中对tailwindcss的智能感知提示&#xff0c;在利用tailwindcss实现html效果布局。非常的方便。 生成CSS

7/8电源连接器航空插头端子

概述 7/8电源连接器是一种工业电源连接器的规格型号之一&#xff0c;常见于工业领域的电力传输和连接应用。它的名称中的“7/8”代表连接器插头的直径尺寸&#xff0c;通常为7/8英寸。这种类型的连接器通常用于较大电流传输和较高功率设备的连接&#xff0c;具有较大的电流承载…

Java 中文官方教程 2022 版(三十九)

原文&#xff1a;docs.oracle.com/javase/tutorial/reallybigindex.html XPath 如何工作 原文&#xff1a;docs.oracle.com/javase/tutorial/jaxp/xslt/xpath.html XPath 规范是各种规范的基础&#xff0c;包括 XSLT 和链接/寻址规范&#xff0c;如XPointer。因此&#xff0c;对…

Ubuntu系统 - 使用不同的libssl库

1 ubuntu-20.04.2.0-desktop-amd64 - 依赖libssl1.1 $ readelf -d mainDynamic section at offset 0x2d60 contains 29 entries:Tag Type Name/Value0x0000000000000001 (NEEDED) Shared library: [libssl.so.1.1]0x0000000000000…

【Java-TesseractOCR】通过Java实现OCR

通过Java实现OCR 一、TesseractOCR二、引入pom训练集下载地址三、引入训练集三、使用 一、TesseractOCR 本文使用的是TesseractOCR进行识别 二、引入pom <dependency><groupId>net.sourceforge.tess4j</groupId><artifactId>tess4j</artifactId&…

多态——C++

这里写目录标题 衔接继承总结继承和组合白箱复用黑箱复用 多态的概念多态的定义以及实现虚函数重写的两个例外协变面试题析构函数的重写 finalvoerride重载隐藏(重定义)重写(覆盖)抽象类什么是抽象类&#xff1f; 实现继承和接口继承多态的原理虚函数表 那多态的调用是怎么实现…

从零开始HashMap

目录 1.HashMap的数据结构 2.put&#xff08;&#xff09;流程 2.1了解扩容机制 2.2扩容三个地方 2.3存入数据步骤 3.HashMap和Hashtable的区别 4.HashMap线程安全的解决办法 4.1Hashtable 4.2Collections 4.3ConcurrentHashMap 线程安全实现机制 1.HashMap的数据结…

14届蓝桥杯 C/C++ B组 T6 岛屿个数 (BFS,FloodFill,填色)

首先拿到这道题不要想着去直接判断环里面的岛屿&#xff0c;这样太困难了&#xff0c;我们可以使用之前做过的题的经验&#xff0c;在输入加入一圈海水&#xff0c;然后从(0,0)点开始BFS&#xff0c;这里进行八向搜索&#xff0c;搜到的0全部都染色成2&#xff0c;假如2能够蔓延…

Vue项目打包配置生产环境去掉console.log语句的方法

一、Vue2项目 使用webpack内置的 terser 工具&#xff0c;在vue.config.js文件加上相应的配置即可。 二、Vue3项目 同样是使用 terser 工具&#xff0c;不过vite没有内置terser&#xff0c;需要手动安装依赖 安装完后在vite.config.js文件加上相应的配置即可。 2024-4-9