概率dp sgu495
题意: 有n个奖品,m个人排队来选礼物,对于每个人,他打开的盒子,可能有礼物,也有可能已经被之前的人取走了,然后把盒子放回原处。为最后m个人取走礼物的期望。
思路1: 排队取,第1个人取到1个,dp[1]=1;后面的人dp[i]=p取到礼物盒子+dp前面的取到礼物盒子=(n-dp[i-1])/n + dp[i-1];
1 #include"bits/stdc++.h" 2 3 #define db double 4 #define ll long long 5 #define vl vector<ll> 6 #define ci(x) scanf("%d",&x) 7 #define cd(x) scanf("%lf",&x) 8 #define cl(x) scanf("%lld",&x) 9 #define pi(x) printf("%d\n",x) 10 #define pd(x) printf("%f\n",x) 11 #define pl(x) printf("%lld\n",x) 12 #define rep(i, n) for(int i=0;i<n;i++) 13 using namespace std; 14 const int N = 1e6 + 5; 15 const int mod = 1e9 + 7; 16 const int MOD = 998244353; 17 const db PI = acos(-1.0); 18 const db eps = 1e-10; 19 const ll INF = 0x3fffffffffffffff; 20 int t; 21 db dp[N]; 22 int n,m; 23 void cal() 24 { 25 dp[1]=1; 26 for(int i=2;i<=m;i++) dp[i]=dp[i-1]+(n-dp[i-1])/n; 27 printf("%f\n",dp[m]); 28 } 29 int main() 30 { 31 32 while(scanf("%d%d",&n,&m)==2){ 33 cal(); 34 } 35 return 0; 36 }
思路2:具体在代码里
1 /* 2 SGU 495 3 题意:n个盒子里装有礼物,m个人随机选择礼物,选完之后空盒子放回 4 问选中的礼物数的期望。 5 6 m个人是独立的。 7 对于每个礼物不被人选中的概率为((n-1)/n)^m 8 那么不被选中的礼物数的期望就是 n*((n-1)/n)^m 9 所以答案就是 n-n*((n-1)/n)^m; 10 11 */ 12 #include<stdio.h> 13 #include<iostream> 14 #include<algorithm> 15 #include<math.h> 16 using namespace std; 17 int main() 18 { 19 int n,m; 20 while(scanf("%d%d",&n,&m)!=EOF) 21 { 22 double p=(double)(n-1)/n; 23 double ans=n-n*pow(p,m); 24 printf("%.10lf\n",ans); 25 } 26 return 0; 27 }