题意
xyq有\(n\)个骰子,第\(i\)个骰子有\(a_i\)面,每次xyq都会把\(n\)个骰子搞一遍,其中的最小值作为结果,问最终结果的期望\(\mod (10^9+7 )\)。
分析
lfx聚聚出的神仙题,瞎写了个\(dp\)解法
设\(dp[i][j]\)为前\(i\)个骰子的点数最小值为\(j\)的概率,有两种情况
- \(dp[i][j]+=(\sum_{k=j+1}^{40}dp[i-1][k])\times \frac{1}{a[i]}\),(前\(i-1\)个骰子的最小值大于\(j\)时,第\(i\)个骰子的点数必须为\(j\))
- \(dp[i][j]+=dp[i-1][j]\times \frac{a[i]-j+1}{a[i]}\),(前\(i-1\)个骰子的最小值等于\(j\)时,第\(i\)个骰子的点数的取值范围为\([~j,a[i]~]\) )
Code
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define ll long long
using namespace std;
const ll inf=1e18;
const int mod=1e9+7;
const int maxn=1e5+10;
int n;
ll a[55],dp[55][55];
ll ksm(ll a,ll b){
ll ret=1;
while(b){
if(b&1) ret=ret*a%mod;
b>>=1;
a=a*a%mod;
}
return ret;
}
int main(){
//ios::sync_with_stdio(false);
//freopen("in","r",stdin);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}sort(a+1,a+n+1);
for(int i=1;i<=a[1];i++) dp[1][i]=ksm(a[1],mod-2);
for(int i=2;i<=n;i++){
for(int j=1;j<=a[i];j++){
ll ret=0;
for(int k=j+1;k<=40;k++) ret=(ret+dp[i-1][k])%mod;
dp[i][j]=ret*ksm(a[i],mod-2)%mod+dp[i-1][j]*(a[i]-j+1)%mod*ksm(a[i],mod-2)%mod;
dp[i][j]%=mod;
}
}
ll ans=0;
for(int i=1;i<=40;i++){
ans=(ans+dp[n][i]*i%mod)%mod;
}
printf("%lld\n",ans);
return 0;
}