SRM 504.5(2-1000pt)

DIV2 1000pt

题意:一群人排队,每次操作由要骰子决定,只要没有人中奖,游戏就不结束。若摇骰子摇出4,则队列第一个人中奖;否则,若摇的是奇数,则第一个人排队到队伍末尾去;否则,第一个人出局。若游戏途中,队列只剩一个人,则直接中奖。若摇了k次骰子仍然没人中奖,则此时队列第一个人自动获奖,游戏结束。给出k,问队列初始时为n个人,此时排在第m个的人中奖的概率有多大。n, m, k <= 10。

解法:普通的概率dp。将题中的k记为num。

   法一:设d[i][j][k]表示当前状态为摇了i次骰子,队列共有j人,排在第k个的中奖的概率。具体状态转移方程见代码,很简单。

   法二:设d[i][j][k]表示由初始状态变成摇了i次骰子后,队列有j个人,初始时排在第m个的人现在排在第k个的概率。状态转移方程同见方程。

tag:概率dp

法一:

 1 // BEGIN CUT HERE
 2 /*
 3  * Author:  plum rain
 4  * score :
 5  */
 6 /*
 7 
 8  */
 9 // END CUT HERE
10 #line 11 "TheTicketsDivTwo.cpp"
11 #include <sstream>
12 #include <stdexcept>
13 #include <functional>
14 #include <iomanip>
15 #include <numeric>
16 #include <fstream>
17 #include <cctype>
18 #include <iostream>
19 #include <cstdio>
20 #include <vector>
21 #include <cstring>
22 #include <cmath>
23 #include <algorithm>
24 #include <cstdlib>
25 #include <set>
26 #include <queue>
27 #include <bitset>
28 #include <list>
29 #include <string>
30 #include <utility>
31 #include <map>
32 #include <ctime>
33 #include <stack>
34 
35 using namespace std;
36 
37 #define CLR(x) memset(x, 0, sizeof(x))
38 #define CLR1(x) memset(x, -1, sizeof(x))
39 #define PB push_back
40 #define SZ(v) ((int)(v).size())
41 #define zero(x) (((x)>0?(x):-(x))<eps)
42 #define out(x) cout<<#x<<":"<<(x)<<endl
43 #define tst(a) cout<<#a<<endl
44 #define CINBEQUICKER std::ios::sync_with_stdio(false)
45 
46 typedef vector<int> VI;
47 typedef vector<string> VS;
48 typedef vector<double> VD;
49 typedef long long int64;
50 
51 const double eps = 1e-8;
52 const double PI = atan(1.0)*4;
53 const int maxint = 2139062143;
54 
55 double d[20][20][20];
56 
57 class TheTicketsDivTwo
58 {
59     public:
60         double find(int n, int m, int num){
61             double t1 = (double) 1 / (double)3, t2 = (double)1 / (double)6;
62             CLR (d);
63             for (int i = 1; i <= n; ++ i)
64                 d[num][i][1] = 1;
65 
66             for (int i = num-1; i >= 0; -- i)
67                 for (int j = 1; j <= n; ++ j)
68                     for (int k = 1; k <= j; ++ k){
69                         if (j == 1) d[i][j][k] = 1;
70                         else if (k == 1) d[i][j][k] = d[i+1][j][j]*0.5 + t2;
71                         else d[i][j][k] = d[i+1][j][k-1]*0.5 + d[i+1][j-1][k-1]*t1;
72                     }
73             return d[0][n][m];
74         }
75         
76 // BEGIN CUT HERE
77     public:
78     void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); }
79     private:
80     template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
81     void verify_case(int Case, const double &Expected, const double &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }
82     void test_case_0() { int Arg0 = 2; int Arg1 = 1; int Arg2 = 1; double Arg3 = 0.16666666666666666; verify_case(0, Arg3, find(Arg0, Arg1, Arg2)); }
83     void test_case_1() { int Arg0 = 2; int Arg1 = 1; int Arg2 = 2; double Arg3 = 0.5833333333333334; verify_case(1, Arg3, find(Arg0, Arg1, Arg2)); }
84     void test_case_2() { int Arg0 = 7; int Arg1 = 7; int Arg2 = 4; double Arg3 = 0.0; verify_case(2, Arg3, find(Arg0, Arg1, Arg2)); }
85     void test_case_3() { int Arg0 = 4; int Arg1 = 2; int Arg2 = 10; double Arg3 = 0.25264033564814814; verify_case(3, Arg3, find(Arg0, Arg1, Arg2)); }
86 
87 // END CUT HERE
88 
89 };
90 
91 // BEGIN CUT HERE
92 int main()
93 {
94 //    freopen( "a.out" , "w" , stdout );    
95     TheTicketsDivTwo ___test;
96     ___test.run_test(-1);
97        return 0;
98 }
99 // END CUT HERE
View Code

法二:

  1 // BEGIN CUT HERE
  2 /*
  3  * Author:  plum rain
  4  * score :
  5  */
  6 /*
  7 
  8  */
  9 // END CUT HERE
 10 #line 11 "TheTicketsDivTwo.cpp"
 11 #include <sstream>
 12 #include <stdexcept>
 13 #include <functional>
 14 #include <iomanip>
 15 #include <numeric>
 16 #include <fstream>
 17 #include <cctype>
 18 #include <iostream>
 19 #include <cstdio>
 20 #include <vector>
 21 #include <cstring>
 22 #include <cmath>
 23 #include <algorithm>
 24 #include <cstdlib>
 25 #include <set>
 26 #include <queue>
 27 #include <bitset>
 28 #include <list>
 29 #include <string>
 30 #include <utility>
 31 #include <map>
 32 #include <ctime>
 33 #include <stack>
 34 
 35 using namespace std;
 36 
 37 #define CLR(x) memset(x, 0, sizeof(x))
 38 #define CLR1(x) memset(x, -1, sizeof(x))
 39 #define PB push_back
 40 #define SZ(v) ((int)(v).size())
 41 #define zero(x) (((x)>0?(x):-(x))<eps)
 42 #define out(x) cout<<#x<<":"<<(x)<<endl
 43 #define tst(a) cout<<#a<<endl
 44 #define CINBEQUICKER std::ios::sync_with_stdio(false)
 45 
 46 typedef vector<int> VI;
 47 typedef vector<string> VS;
 48 typedef vector<double> VD;
 49 typedef long long int64;
 50 
 51 const double eps = 1e-8;
 52 const double PI = atan(1.0)*4;
 53 const int maxint = 2139062143;
 54 
 55 double d[20][20][20];
 56 
 57 class TheTicketsDivTwo
 58 {
 59     public:
 60         double find(int n, int m, int num){
 61             double t1 = (double) 1 / (double)3, t2 = (double)1 / (double)6;
 62             CLR (d);
 63             d[0][n][m] = 1.0;
 64             for (int i = 1; i <= num; ++ i)
 65                 for (int j = 1; j <= n; ++ j)
 66                     for (int k = 1; k <=j; ++ k){
 67                         if (j == k){
 68                             if (j == 1) d[i][1][1] = d[i-1][j+1][j+1] * t1;
 69                             else d[i][j][k] = d[i-1][j][1] * 0.5 + d[i-1][j+1][j+1] * t1;
 70                         }
 71                         else{
 72                             d[i][j][k] = d[i-1][j][k+1] * 0.5;
 73                             if (j < n) d[i][j][k] += d[i-1][j+1][k+1] * t1;
 74                         }
 75                     }
 76 
 77             double ans = 0;
 78             for (int i = 0; i < num; ++ i)
 79                 for (int j = 1; j <= n; ++ j)
 80                     ans += d[i][j][1] * (j == 1 ? 1 : t2);
 81             for (int i = 1; i <= n; ++ i)
 82                 ans += d[num][i][1];
 83             return ans;
 84         }
 85         
 86 // BEGIN CUT HERE
 87     public:
 88     void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); }
 89     private:
 90     template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
 91     void verify_case(int Case, const double &Expected, const double &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }
 92     void test_case_0() { int Arg0 = 2; int Arg1 = 1; int Arg2 = 1; double Arg3 = 0.16666666666666666; verify_case(0, Arg3, find(Arg0, Arg1, Arg2)); }
 93     void test_case_1() { int Arg0 = 2; int Arg1 = 1; int Arg2 = 2; double Arg3 = 0.5833333333333334; verify_case(1, Arg3, find(Arg0, Arg1, Arg2)); }
 94     void test_case_2() { int Arg0 = 7; int Arg1 = 7; int Arg2 = 4; double Arg3 = 0.0; verify_case(2, Arg3, find(Arg0, Arg1, Arg2)); }
 95     void test_case_3() { int Arg0 = 4; int Arg1 = 2; int Arg2 = 10; double Arg3 = 0.25264033564814814; verify_case(3, Arg3, find(Arg0, Arg1, Arg2)); }
 96 
 97 // END CUT HERE
 98 
 99 };
100 
101 // BEGIN CUT HERE
102 int main()
103 {
104 //    freopen( "a.out" , "w" , stdout );    
105     TheTicketsDivTwo ___test;
106     ___test.run_test(-1);
107        return 0;
108 }
109 // END CUT HERE
View Code

 

 

posted @ 2013-12-12 23:12  Plumrain  阅读(222)  评论(0编辑  收藏  举报