[Tkey] CodeForces 1267G Game Relics
太神了这题,膜拜出题人 orz。
思考一
首先是大家都提到的一点,先抽卡再买。这里来做个数学分析。
假设我们还剩 \(k\) 种没有买,其实我们是有式子来算出它的花费期望的。WIKI 上提到,假设一个事件的概率为 \(p\),则遇到它的期望为 \(\frac{1}{p}\),因此,对于这个题,抽到一个新物品的概率显然为 \(\frac{k}{n}\),那么期望次数就为 \(\frac{n}{k}\),这里面除了最后一次之外,其余的次数的花费都为 \(x-\frac{x}{2}=\frac{x}{2}\),而最后一次的花费恰好为 \(x\),因此可以得出有 \(k\) 种没买的情况下,抽到新物品的期望花费公式:
\]
可以看出这个式子是关于 \(k\) 单调递增的,也就是说,越晚抽卡,花费的代价越大,因此才有了上述的结论:先抽卡再买。
思考二
既然我们能直接算出期望了,那我们直接比较一下抽卡和买哪个更赚不就行了吗。现在抽卡的期望我们有了,还需要一个买东西的期望。其实,因为每个东西的价值都是固定的,所以这个期望实际上就是平均数,那么我们算出这个平均数,每次都和当前的抽卡期望比较,选个最小的执行不就行了,搞定!紫题也不过如此。
但是不对,有点小问题。因为每个物品的价值都是不一样的,我们抽到不同的物品,最后计算出来的平均数也不一样。难道要枚举一遍全部的可能情况,再算一个平均数的平均数?又或者还要分情况讨论?那不就变成搜了吗,晕。
思考三
不对,除了搜还能写 DP,但是就是不知道状态怎么设计。
想想看,我们现在需要的东西有什么。需要计算抽卡期望,那么我们需要的东西就是当前剩余的物品个数,还有一个是平均数,那我们直接用剩余价值除以剩余个数不就行了吗!开一个两个维度的 DP:剩余个数,剩余价值。发现它变成了一个背包 DP。
现在来想状态转移。其实到这一步就和常规背包 DP 差不多了。定义初始状态 \(f_{n,sum}=sum\),即不抽卡的期望花费为总价值,然后从剩余容量由大到小开始枚举所有物品,然后尝试转移就行了。
思考四
本来以为都快过了,但是写一半卡住了。
具体是卡在状态转移的时候,突然发现这个转移根本就没法实现。因为我们每次转移可能的来源有两个:一个是购买,一个是抽卡。买还好说,但是抽卡不行,因为不是整数,而我们没办法访问一个小数下标。
那么怎么办呢,感觉又到了瓶颈了。
首先这个思路是绝对正确的,我们整理一下现在都有什么了。我们可以求出在某个状态下的最优代价,那么,假如我们再维护一个出现概率的话,就能根据期望的定义,直接用概率乘代价去算了。那么我们不妨把我们设计的 DP 数组改一下,不维护期望了,改成维护当前状态的概率,再求一下抽卡期望和平均值的最小值,二者一乘就是答案。又因为这个题的总方案数是一定的(可以用组合数求),那么我们不妨再转换一下思路,改成求当前状态的总方案数,和总方案数一比就是答案。
思考五
我们在思路整理的时候忽略了一些小细节,比如,如果当前的最优策略是抽卡,则若没抽中,下次的最优策略还是抽卡,直到抽到一个新的。简单证明一下,假如你抽卡没抽中,那么除了钱少了点,此外什么都没变,因此 \(E(k)\) 和平均数完全不会有任何变化。知道了这点,我们才能用 \(E(k)\) 这样一条路走到黑的模型来计算答案。
还有一点,打完提交的时候莫名其妙 RE 了,后来发现是阶乘乘炸了(\(100!\) 确实还挺大的),然后把阶乘函数改成 Double 就过了,会丢精度,但是不影响答案。
代码
#include<bits/stdc++.h>
using namespace std;
#define div *1.0/
int n,x;
int c[101];
double f[101][10001];
long double fac[101];
inline void prework(){
fac[0]=1;
for(int i=1;i<=100;++i){
fac[i]=fac[i-1]*i;
}
}
inline double E(int k){
return (n div k -1)*(x div 2)+x;
}
inline double C(int x,int y){
return fac[x] div (fac[y]*fac[x-y]);
}
int main(){
int sum=0;
cin>>n>>x;
prework();
for(int i=1;i<=n;++i){
cin>>c[i];
sum+=c[i];
}
f[n][sum]=1;
for(int i=1;i<=n;++i){
for(int j=0;j<=n-1;++j){
for(int k=0;k<=sum-c[i];++k){
f[j][k]+=f[j+1][k+c[i]];
}
}
}
long double ans=0;
for(int i=1;i<=n;++i){
for(int j=0;j<=sum;++j){
ans+=(f[i][j] div C(n,n-i)) * min(j div i,E(i));
}
}
printf("%.20Lf",ans);
}
[Tkey] CodeForces 1267G Game Relics的更多相关文章
- python爬虫学习(5) —— 扒一下codeforces题面
上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
- 【Codeforces 738C】Road to Cinema
http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...
- 【Codeforces 738A】Interview with Oleg
http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...
- CodeForces - 662A Gambling Nim
http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...
- CodeForces - 274B Zero Tree
http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...
- CodeForces - 261B Maxim and Restaurant
http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...
- CodeForces - 696B Puzzles
http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...
- CodeForces - 148D Bag of mice
http://codeforces.com/problemset/problem/148/D 题目大意: 原来袋子里有w只白鼠和b只黑鼠 龙和王妃轮流从袋子里抓老鼠.谁先抓到白色老鼠谁就赢. 王妃每次 ...
- CodeForces - 453A Little Pony and Expected Maximum
http://codeforces.com/problemset/problem/453/A 题目大意: 给定一个m面的筛子,求掷n次后,得到的最大的点数的期望 题解 设f[i]表示掷出 <= ...
随机推荐
- 网络基础 CAS协议学习总结
架构介绍 系统组件 CAS服务器和客户端构成了CAS系统体系结构的两个物理组件,它们通过各种协议进行通信. CAS服务器 CAS服务器是基于Spring Framework构建的Java servle ...
- c++17
std::variant<std::string,int,float>://作为联合体 using va = std::variant<std::string, int, float ...
- RPA处理京东滑块拼图验证码
在进行京东商家后台企业账号的RPA自动化操作过程中,登录环节是必不可少的步骤.然而,这一过程中有时会遇到一种特殊的验证机制--滑块拼图验证码,它的突然出现如同一道屏障,阻碍了自动化的顺利进行.因为只有 ...
- 【VMware】 桥接网路发现无法Ping通原因
解决方案参考: https://blog.csdn.net/weixin_33856370/article/details/92420910 设置好的同网段的三台虚拟机这次开机连不上网了 仔细发现VM ...
- 哈哈哈,我就说未来要研发无人的AI潜艇嘛 —— 说啥来啥 —— AI驱动的无人潜艇
相关: 沉默5个月后,美国对华发出挑战书,万没想到,中方打法早就变了
- 模仿学习算法:Data Aggregation Approach: DAGGER算法——Mixing policy
论文: <A Reduction of Imitation Learning and Structured Prediction to No-Regret Online Learning> ...
- 外网的一个还不错的高性能计算教程: High Performance Computing
地址: https://info.gwdg.de/wiki/doku.php?id=wiki:hpc:start =========================================== ...
- 【转载】 python鸭子类型与protocol
版权声明:本文为CSDN博主「yuanzhoulvpi」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/yuan ...
- Temperature 题解
前言 题目链接:洛谷:SPOJ:Hydro & bzoj. 题意简述 有一个长度为 \(n\) 的序列,每个位置值的范围为 \([L_i, R_i]\) 内,求原序列可能的最长不降子串长度. ...
- vite创建的react项目如何兼容低版本安卓,低版本安卓不支持es6语法
Vite 是一个现代化的前端构建工具,默认情况下,它会生成基于 ES6+ 的代码.这对于大多数现代浏览器来说是没有问题的,但对于一些较旧版本的安卓浏览器可能会遇到兼容性问题. 为了使 Vite 创建的 ...