Bloodsucker ###K ###K ###K ###K //K

题目链接:https://zoj.pintia.cn/problem-sets/91827364500/problems/91827369029
题意:开始有1个吸血鬼 n-1个人,每天任意选2个人,如果其中一个是人,一个是吸血鬼的话,那么有p的概率

使得这个人也被感染成吸血鬼,问全部人变成吸血鬼的期望天数

思路:期望dp    考虑转移的时候状态来源 只有有人感染和没有人感染, 那么先求出从当前状态到下个状态中有人感染的概率pp=i*(n-i)/C(2,n)  i个选一个,n-i选一个 

除以n个选2个  pp*=p 代表 选对人后再发生感染的概率  最后当前状态= 下个状态*感染概率+当前状态*没感染概率+1天数 

即dp[i]=dp[i+1]*pp+dp[i]*(1-pp)+1.0   化简后 即 dp[i]=dp[i+1]+1.0/pp

 

因为期望性质 所以只能逆推  dp[i] 代表目前有i个吸血鬼,全部人变成吸血鬼的天数 dp[n]=0 逆推求dp[1]

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define pb push_back
 5 const int maxn =1e5+10;
 6 const int mod=1e9+7;
 7 double dp[maxn];
 8 
 9 
10 int main()
11 {
12     ios::sync_with_stdio(false);
13     cin.tie(0);
14     int t;
15     cin>>t;
16     while(t--)
17     {
18         int n;
19         cin>>n;
20         double p;
21         cin>>p;
22         dp[n]=0;
23         for(int i=n-1;i>=1;i--)
24         {
25             double pp=2.0*i*(n-i)/((double)n*(n-1));
26             pp*=p;
27             dp[i]=(dp[i+1]*pp+1.0)/pp;
28         }
29         cout<<fixed<<setprecision(3)<<dp[1]<<'\n';
30 
31     }
32 
33 
34 
35 
36 
37 
38 }
View Code

 

https://vjudge.net/problem/SPOJ-FAVDICE  同类题   问一个骰子有n面, 能每个面都投出来的期望次数为多少

附上代码   

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define pb push_back
 5 const int maxn =1e5+10;
 6 const int mod=1e9+7;
 7 double dp[1110];
 8 
 9 
10 int main()
11 {
12     ios::sync_with_stdio(false);
13     cin.tie(0);
14     int t;
15     cin>>t;
16     while(t--)
17     {
18        int n;
19        cin>>n;
20        dp[0]=0;
21        for(int i=1;i<=n;i++)
22        {
23            double pp=(n-i+1)/(double)n;
24            dp[i]=(dp[i-1]*pp+1.0)/pp;
25        }
26        cout<<fixed<<setprecision(2)<<dp[n]<<'\n';
27 
28     }
29 
30 
31 
32 
33 
34 
35 }
View Code

 

posted @ 2020-11-03 14:50  canwinfor  阅读(88)  评论(0)    收藏  举报