概率DP的题目,一直就不会做这类题目。
dp[s]表示状态为s的时候再买多少张牌可以买全,表示的是一个期望值。
dp[s] = 1 + P(empty) * dp[s] + P(had) * dp[s] + P(new) * dp[nst]。
从而可以解dp[s]。
1 /* 4336 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 43 const int maxn = 20; 44 double p[maxn]; 45 double dp[1<<maxn]; 46 int n; 47 48 void solve() { 49 int mst = 1 << n; 50 int mask = mst - 1; 51 dp[mask] = 0; 52 53 per(i, 0, mask) { 54 double tmp = 0.0; 55 56 dp[i] = 1.0; 57 rep(j, 0, n) { 58 if (i & (1<<j)) 59 continue; 60 dp[i] += p[j] * dp[i|(1<<j)]; 61 tmp += p[j]; 62 } 63 dp[i] /= tmp; 64 } 65 66 double ans = dp[0]; 67 printf("%.06lf\n", ans); 68 } 69 70 int main() { 71 ios::sync_with_stdio(false); 72 #ifndef ONLINE_JUDGE 73 freopen("data.in", "r", stdin); 74 freopen("data.out", "w", stdout); 75 #endif 76 77 while (scanf("%d", &n)!=EOF) { 78 rep(i, 0, n) 79 scanf("%lf", &p[i]); 80 solve(); 81 } 82 83 #ifndef ONLINE_JUDGE 84 printf("time = %d.\n", (int)clock()); 85 #endif 86 87 return 0; 88 }