HDU 4336 概率DP 状压
用d(S)表示所收集到卡片种类状态为S时还需买多少包小浣熊(这是我YY的)的期望。
则有方程d(S) = 1 + (P(空) + P(有)) * d(S) + P(无) * d(T)
其中P(空)表示没有收集到卡片,P(有)表示收集到的是已经有的卡片,P(无)表示收集到新的卡片。
而且 P(空) + P(有) + P(无) = 1,T表示收集到新卡片后的状态
整理以后得到d(S) = (1 + d(T)) / P(无)
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 25; 8 double d[1100000]; 9 double p[1100000]; 10 11 int main() 12 { 13 int n; 14 while(scanf("%d", &n) == 1 && n) 15 { 16 for(int i = 0; i < n; i++) scanf("%lf", p + i); 17 int tot = (1 << n) - 1; 18 d[tot] = 0; 19 for(int i = tot - 1; i >= 0; i--) 20 { 21 double wu = 0; 22 d[i] = 1; 23 for(int j = 0; j < n; j++) if((i & (1 << j)) == 0) 24 { 25 wu += p[j]; 26 d[i] += p[j] * d[i | (1 << j)]; 27 } 28 d[i] /= wu; 29 } 30 printf("%.6f\n", d[0]); 31 } 32 33 return 0; 34 }