CF1267G Game Relics
CF1267G Game Relics
有 \(n\) 个物品,你可以进行下面两种操作:
花费 \(c_i\) 元购买第 \(i\) 个物品。
花费 \(x\) 元抽奖,随机获得一个物品 \(i\)。若你已经拥有第 \(i\) 个物品,则你本次抽奖的花费改为 \(\dfrac{x}{2}\) 元。
求获得所有物品的期望最小花费。
\(1 \leq n \leq 100\),\(1 \leq x \leq c_i \leq 10000\),\(\sum\limits_{i=1}^{n} c_i \leq 10000\)。
首先我们有如下的观察:
性质 \(1\):如果选择抽奖,则会一直选择抽奖,直到抽到新的物品为止。
证明显然,考虑若抽奖在当前状态下是最优决策,则没有抽到新的物品时状态不变,继续抽奖仍然是最优决策。
此时我们不妨设已经拥有了 \(k\) 个物品,则抽到一个新物品的期望花费为 \(\sum\limits_{i=0}^{\infty} (\dfrac{k}{n})^i \times \dfrac{n-k}{n} \times (\dfrac{i}{2} + 1) \times x\),经过计算可以化简为 \(\dfrac{x}{2} \times (1 + \dfrac{n}{n-k})\)。此时第二个操作等价于花费 \(\dfrac{x}{2} \times (1 + \dfrac{n}{n-k})\) 元随机获得一个当前没有的物品 \(i\)。通过这一点,我们可以得出新的观察:
性质 \(2\):一定先抽若干次奖,再购买剩下的所有物品。
感性理解一下,越往后抽奖的花费越高,而购买物品的花费是固定的,显然先抽奖再买物品更优。
此时我们发现,购买物品的顺序没有影响,可以看成随机购买一个当前没有的物品。假设当前已经拥有的 \(k\) 个物品价值和为 \(s\) 元,\(n\) 个物品的总价值和为 \(S\) 元,则操作可以变为下面的形式:
-
花费 \(\dfrac{S-s}{n-k}\) 元随机获得一个当前没有的物品 \(i\)。
-
花费 \(\dfrac{x}{2} \times (1 + \dfrac{n}{n-k})\) 元随机获得一个当前没有的物品 \(i\)。
显然每步都可以将两者取最小值,即:
- 花费 \(\min(\dfrac{S-s}{n-k},\dfrac{x}{2} \times (1 + \dfrac{n}{n-k}))\) 元随机获得一个当前没有的物品 \(i\)。
我们考虑设计 \(dp_{k,s}\) 表示在 \(k\) 和 \(s\) 的情况下拥有的物品方案数,则答案可以简单的看作每一步的期望和,也就是:
结束了。
复杂度 \(O(n^2S)\)。
#include<iostream>
#include<cstdio>
using namespace std;
int n,S,c[110];
double x,fact[110],dp[110][10010];
double calc(int k,int s){
return min(1.0*(S-s),x*(2*n-k)/2)/(n-k);
}
int main(){
scanf("%d %lf",&n,&x);
fact[0]=1;
for(int i=1;i<=n;i++){
scanf("%d",&c[i]);
S+=c[i];
fact[i]=fact[i-1]*i;
}
dp[0][0]=1;
for(int i=1;i<=n;i++){
for(int k=i;k>=1;k--){
for(int s=S;s>=c[i];s--){
dp[k][s]+=dp[k-1][s-c[i]];
}
}
}
double ans=0;
for(int k=0;k<n;k++){
for(int s=0;s<=S;s++){
ans+=dp[k][s]*calc(k,s)*fact[k]*fact[n-k]/fact[n];
}
}
printf("%.15lf",ans);
return 0;
}

浙公网安备 33010602011771号