CF1267G-Game Relics【数学期望,dp】
正題
題目鏈接:https://www.luogu.com.cn/problem/CF1267G
題目大意
給出nnn個物品,你可以進行如下操作
- 花費xxx獲得隨機一個物品。
 - 花費cic_ici?獲得第iii個物品。
 
1≤n≤100,1≤x≤10000,∑ai≤1041\leq n\leq 100,1\leq x\leq 10000,\sum a_i\leq 10^41≤n≤100,1≤x≤10000,∑ai?≤104
解題思路
一個顯然的策略是我們先roll完再買,所以我們可以分開考慮兩部分先。
首先假設我們roll到了xxx個物品,顯然所有大小為xxx的物品集合都是等概率出現的。而至于roll出xxx個物品的期望花費我們也很好算。
但是我們顯然很難從一種情況下的下一步方案考慮,因為能到達每個方案的期望都是不同的,而我們不可能記錄所有方案。
但是有一個很巧妙的方法,我們花錢也可以視為隨意rollrollroll物品,假設目前沒有獲得的物品費用和為sss,個數為kkk,那么我們就可以視為花費sk\frac{s}{k}ks?的期望隨機rollrollroll出一個物品。
此時兩種方案造成的結果都是多一個隨機未獲得物品,但是花費不同,我們直接取minminmin即可。
那么現在的做法已經很顯然了,設fi,jf_{i,j}fi,j?表示iii個物品的集合中花費和為jjj的概率,然后考慮兩種方案的哪個更優就好了。
時間復雜度:O(n∑ai)O(n\sum a_i)O(n∑ai?)
code
#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; }總結
以上是生活随笔為你收集整理的CF1267G-Game Relics【数学期望,dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: dw怎么显示css效果(dw中css怎么
 - 下一篇: xml怎么用记事本(xml怎么用记事本打