At382 E - Expansion Packs
E.Expansion Packs
题意简述
有无限个独立的牌组,每个牌组有n张卡组成,每张卡是稀有卡的概率位 \(p_i\) ,求抽到稀有卡的数量不小于x的需要抽的卡组数量的期望.
解题思路
显然每个牌组拥有稀有牌的数量也是一个不确定的,可以用一个数组存储当前牌组有 \(i\) 张稀有牌的概率是多少,转移方程为 \(f[i][j]=f[i-1][j-1]·p[i]+f[i-1][j]·1-p[i]\),所求出的\(f[n][i]\)就是每个牌组有 \(i\) 张牌的概率,确定这个之后思考牌组概率与最终需要期望的关系。注意到,期望可以通过概率进行逐步转移,考虑动态规划。定义 \(ans[i]\) 为抽到稀有卡数量不小于x至少需要抽到卡组数量的期望,那么就可以得到转移方程 \(ans[i]=\sum_{j=0} ^n ans[max(i-j,0)]·f[j]+1\),由于 \(ans[i]\) 能从 \(ans[i]·f[0]\) 转移过来,所以需要移项,除到右边 \(ans[i]=ans[i]·f[0]+\sum_{j=1} ^n ans[max(i-j,0)]·f[j]+1\),所以有\(ans[i]=(\sum_{j=1} ^n ans[max(i-j,0)]·f[j]+1)/(1-f[0])\)
AC code
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const ll inf=1e18;
int main(){
cin.tie(0)->ios::sync_with_stdio(false);
int n,m;
cin>>n>>m;
vector<long double>p(n+1);
for(int i=1;i<=n;i++){
int x;cin>>x;
p[i]=1.0L*x/100;
}
vector<vector<long double> >f(n+1,vector<long double>(n+1));
f[0][0]=1.0;
for(int i=1;i<=n;i++){
f[i][0]=f[i-1][0]*(1.0L-p[i]);
for(int j=1;j<=n;j++){
f[i][j]=f[i-1][j-1]*p[i]+f[i-1][j]*(1.0L-p[i]);
}
}
vector<long double>ans(m+1);
for(int i=1;i<=m;i++){
ans[i]=1.0L;
for(int j=1;j<=n;j++){
ans[i]+=ans[max(i-j,0)]*f[n][j];
}
ans[i]/=(1.0L-f[n][0]);
}
cout<<fixed<<setprecision(16)<<ans[m]<<endl;
return 0;
}

浙公网安备 33010602011771号