【CF1267G】Game Relics(期望)
- 有 \(n\) 个物品,第 \(i\) 个物品直接购买的价格为 \(c_i\)。
- 除了直接购买,你还可以以 \(x\) 的代价等概率抽取一件物品,如果已经获得过抽到的物品则退还 \(\frac x2\)。
- 求获得所有物品的最小期望花费。
- \(1\le n\le100\),\(c_i\ge x\),\(\sum c_i\le 10^4\)
先抽卡再购买
考虑我们一定是选择先抽卡再购买。
因为假如我们先购买再抽卡,只会让抽取到新物品的概率变小,而抽重复退还的 \(\frac x2\) 又比购买花费更小,因此肯定不优。
假设当前已经有 \(i\) 个物品,拥有的物品价值和为 \(j\)(并设所有物品价值总和为 \(t\))。
则,此时抽取出一个新物品的概率为 \(\frac{n-i}n\),也就是说期望次数为 \(\frac n{n-i}\),那么期望代价就是 \((\frac n{n-i}+1)\frac x2\)。而剩余物品总价值为 \(t-j\),也就是说抽取出的物品的期望价值为 \(\frac{t-j}{n-i}\)。
显然,如果期望代价比期望价值更大,那么我们肯定不会再选择去抽卡,而是直接购买了。
实际上可以利用这两个式子再次证明开始的结论:\((\frac n{n-i}+1)\frac x2 > \frac{t-j}{n-i}\Leftrightarrow (2n-i)\frac x2>t-j\),则随着 \(i\) 的增大,左式减少 \(\frac x2\),右式减少 \(c_{k}\),因为右式减少得更多,不等式必然依旧成立。
随机购买
如果直接考虑什么时候转成全部购买,需要保证这一次抽卡代价更大,且上一次抽卡代价更小,比较麻烦,复杂度偏高。
所以需要再来一个转化,就是即便确定了要直接购买了,我们不一次性全买下来,而是随机去一个一个购买,容易发现这与原问题等价。
现在既然完全随机了,那么出现任意一类局面的概率就可以直接计算了。
仍然假设当前已经有 \(i\) 个物品,拥有的物品价值和为 \(j\),可以简单背包求出每一类局面的个数。
而这类局面的期望代价就是先前提到的两种期望代价的较小值,即 \(\min\{(\frac n{n-i}+1)\frac x2,\frac{t-j}{n-i}\}\)。
由于每种局面出现概率都是 \(\frac1{C_n^i}\),对同一类局面可以直接给答案加上贡献乘上这类局面种数。
代码:\(O(n^2\sum c_i)\)
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Rg register
#define RI Rg int
#define Cn const
#define CI Cn int&
#define I inline
#define W while
#define N 100
#define V 10000
#define DB double
using namespace std;
int n,x,c[N+5];DB g[N+5][V+5],C[N+5][N+5];
int main()
{
RI i,j,k;for(scanf("%d%d",&n,&x),i=1;i<=n;++i) scanf("%d",c+i);
for(C[0][0]=i=1;i<=n;++i) for(C[i][0]=j=1;j<=i;++j) C[i][j]=C[i-1][j-1]+C[i-1][j];//预处理组合数
DB t=0;for(g[0][0]=i=1;i<=n;t+=c[i++]) for(j=i-1;~j;--j) for(k=t;~k;--k) g[j+1][k+c[i]]+=g[j][k];//背包预处理每种局面数
DB ans=0;for(i=0;i^n;++i) for(j=0;j<=t;++j) ans+=min((1.0*n/(n-i)+1)*x/2,(t-j)/(n-i))*g[i][j]/C[n][i];//枚举局面计算期望
return printf("%.12lf\n",ans),0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?