D. Jon and Orbs (概率dp)
阿新 • • 發佈:2020-12-24
技術標籤:DP
D. Jon and Orbs (概率dp)
題意:給定 k k k種龍晶, q q q個詢問,每天產生一種龍晶,產生每種龍晶概率相等,每個詢問給定 p p p,求產生 k k k種龍晶的概率 ≥ ( p − ε ) 2000 \ge \dfrac{(p-\varepsilon)}{2000} ≥2000(p−ε) 的最小天數。
思路:概率
d
p
dp
dp,令
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示第
i
i
i天產生
j
j
j種龍晶的概率,有轉移方程:
d
p
[
i
]
[
j
]
=
d
p
[
i
−
1
]
[
j
]
×
j
k
+
d
p
[
i
−
1
]
[
j
−
1
]
×
k
−
(
j
−
1
)
k
dp[i][j]=dp[i-1][j]\times \dfrac{j}{k}+dp[i-1][j-1]\times \dfrac{k-(j-1)}{k}
dp[i][j]=dp[i−1][j]×kj+dp[i−1][j−1]×kk−(j−1)
因為天數不確定,可開足夠大的第一維,或者滾動陣列去掉第一維,裡層迴圈倒著轉移即可。
然後每次求出第 i i i天的情況後,預處理出 a n s [ p ] ans[p] ans[p]陣列。
需要注意的是 d p [ i ] [ 0 ] = ( i = = 0 ) 1 : 0 dp[i][0]=(i==0)1:0 dp[i][0]=(i==0)1:0。
程式碼
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int k,q;
double dp[N];
int a[N];
int main(){
scanf("%d%d" ,&k,&q);
dp[0]=1;
for(int i=1,p=1;p<=1000;i++){
for(int j=k;j;j--)
dp[j]=dp[j]*j/k+dp[j-1]*(k-j+1)/k;
while(p<=1000&&dp[k]*2000>=p-1e-7) a[p++]=i;
dp[0]=0;
}
while(q--){
int p;scanf("%d",&p);printf("%d\n",a[p]);
}
return 0;
}