CF1267G-Game Relics【数学期望,dp】

1|0正题

题目链接:https://www.luogu.com.cn/problem/CF1267G


1|1题目大意

给出n个物品,你可以进行如下操作

  • 花费x获得随机一个物品。
  • 花费ci获得第i个物品。

1n100,1x10000,ai104


1|2解题思路

一个显然的策略是我们先roll完再买,所以我们可以分开考虑两部分先。

首先假设我们roll到了x个物品,显然所有大小为x的物品集合都是等概率出现的。而至于roll出x个物品的期望花费我们也很好算。

但是我们显然很难从一种情况下的下一步方案考虑,因为能到达每个方案的期望都是不同的,而我们不可能记录所有方案。

但是有一个很巧妙的方法,我们花钱也可以视为随意roll物品,假设目前没有获得的物品费用和为s,个数为k,那么我们就可以视为花费sk的期望随机roll出一个物品。

此时两种方案造成的结果都是多一个随机未获得物品,但是花费不同,我们直接取min即可。

那么现在的做法已经很显然了,设fi,j表示i个物品的集合中花费和为j的概率,然后考虑两种方案的哪个更优就好了。

时间复杂度:O(nai)


1|3code

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,sum; double ans,x,f[110][110000]; int main() { scanf("%d%lf",&n,&x);x/=2.0; f[0][0]=1; for(int i=1,a;i<=n;i++){ scanf("%d",&a);sum+=a; for(int j=i;j>=1;j--) for(int k=sum;k>=a;k--) f[j][k]+=f[j-1][k-a]*j/double(n-j+1); } for(int i=1;i<=n;i++) for(int j=0;j<=sum;j++) if(f[i][j]!=0.0) ans=(ans+f[i][j]*min(((double)n/i+1.0)*x,(double)j/i)); printf("%.12lf\n",ans); return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/15841139.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示