[spoj Favorite Dice ][期望dp]

(1)https://vjudge.net/problem/SPOJ-FAVDICE

题意:有一个n面的骰子,每一面朝上的概率相同,求所有面都朝上过至少一次的总次数期望。

题解:令dp[i]表示 i 面满足条件的期望次数,则有 dp[i]=$sum_{j=1}^{i-1}$(Pj*(本次操作对最终期望的贡献+dp[i]))+$sum_{j=1}^{n-(i-1)}$(Qj*(本次操作对最终期望的贡献+dp[i-1])),其中Pj表示出现已经出现过数字的概率,由于是等概率事件,所以这里所有的Pj都是1/n,同理Qj都是1/n,这道题目求的是次数,所以每次操作对最终期望的贡献都是1,所以这道题写下来就是dp[i]=$sum_{j=1}^{i-1}$((1/n+dp[i])+$sum_{j=1}^{n-(i-1)}$((1/n)),化简整理可得转移方程dp[i]=dp[i-1]+n/(n-(i-1))

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 //#define io_test
10 #define debug(x) cout<<x<<"$$$$"<<endl;
11 typedef long long ll;
12 double dp[1005];
13 int main()
14 {
15 #ifdef io_test
16     freopen("in.txt","r",stdin);
17     freopen("out.txt","w",stdout);
18 #endif // io_test
19     int t;
20     scanf("%d",&t);
21     while(t--){
22         int n;
23         scanf("%d",&n);
24         dp[1]=1;
25         for(int i=2;i<=n;i++){
26             dp[i]=dp[i-1]+1.0*n/(n-(i-1));
27            // debug(dp[i]);
28         }
29         printf("%.2lf
",dp[n]);
30     }
31     return 0;
32 }
View Code

(2)http://2050.acmclub.cn/contests/contest_showproblem.php?pid=1001&cid=2

题意:有n+m条路,其中n条是正确的路,走每条路消耗的时间为ai,正确的路通往终点,剩下m条为错误的路,走每条路消耗的时间为bi,求到终点用时的期望是否大于y

题解:令dp[i]表示第i次找到正确的路的期望时间,显然dp[0]=0,而最后要求的时间期望就是dp[1],则效仿上题有dp[1]=$sum_{i=1}^{m}$(Pi*(bi+dp[1]))+$sum_{i=1}^{n}$(Qi*(ai+dp[0])),由于是等概率事件,所以Pi和Qi都是1/(n+m),所以dp[1]=$sum_{i=1}^{m}$((1/(n+m))*(bi+dp[1]))+$sum_{i=1}^{n}$((1/(n+m)*ai)),化简得到dp[1]=($sum_{i=1}^{n}$ai+$sum_{i=1}^{m}$bi)/n

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 //#define io_test
10 #define debug(x) cout<<x<<"$$$$"<<endl;
11 typedef long long ll;
12 int a[15],b[15];
13 int main()
14 {
15 #ifdef io_test
16     freopen("in.txt","r",stdin);
17     freopen("out.txt","w",stdout);
18 #endif // io_test
19     int t;
20     scanf("%d",&t);
21     while(t--){
22         int n,m,y;
23         ll sum1=0;
24         ll sum2=0;
25         scanf("%d%d%d",&n,&m,&y);
26         for(int i=1;i<=n;i++){scanf("%d",&a[i]);sum1+=a[i];}
27         for(int i=1;i<=m;i++){scanf("%d",&b[i]);sum2+=b[i];}
28         if(sum1+sum2>n*y){
29             printf("Wait
");
30         }
31         else{
32             printf("Go
");
33         }
34     }
35     return 0;
36 }
View Code
原文地址:https://www.cnblogs.com/MekakuCityActor/p/10694029.html