hdu_状压dp

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=5816

大牛的链接:

http://www.cnblogs.com/WABoss/p/5754721.html

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <ctime>
 8 #include <queue>
 9 #include <list>
10 #include <set>
11 #include <map>
12 using namespace std;
13 #define INF 0x3f3f3f3f
14 typedef long long LL;
15 
16 LL fact[25], dp[1 << 20];
17 int x[25];
18 int main()
19 {
20     int t, p, n, m;
21     fact[0] = 1;
22     for(int i = 1; i <= 20; i++)
23         fact[i] = fact[i - 1] * i;
24     scanf("%d", &t);
25     while(t--)
26     {
27         scanf("%d %d %d", &p, &n, &m);
28         int N = n + m;
29         for(int i = n; i < N; i++)
30             scanf("%d", x + i);
31         memset(dp, 0, sizeof(dp));
32         dp[0] = 1;
33         for(int i = 0; i < (1 << N); i++)
34         {
35             if(dp[i] == 0)
36                 continue;
37             int a = 0, b = 0, dam = 0;            
38             for(int j = n; j < N; j++)
39             {
40                 if((1 << j) & i){
41                     b++;
42                     dam += x[j];
43                 }
44             }
45             if(dam >= p)
46                 continue;
47             for(int j = 0; j < n; j++)
48             {
49                 if((1 << j) & i)
50                     a++;
51             }
52             if(a - b + 1 <= 0)
53                 continue;
54             for(int j = 0; j < N; j++)
55             {
56                 if((1 << j) & i) continue;
57                 dp[i ^ (1 << j)] += dp[i];
58             }
59         }
60         LL r1 = 0, r2 = fact[N];
61         for(int i = 0; i < (1 << N); i++)
62         {
63             if(dp[i] == 0)
64                 continue;
65             int a = 0, b = 0, dam = 0;            
66             for(int j = n; j < N; j++)
67             {
68                 if((1 << j) & i){
69                     b++;
70                     dam += x[j];
71                 }
72             }
73             for(int j = 0; j < n; j++)
74             {
75                 if((1 << j) & i)
76                     a++;
77             }
78             if(dam >= p)
79                 r1 += dp[i] * fact[N - a - b];
80         }
81         LL te = __gcd(r1, r2);
82         printf("%lld/%lld
", r1 / te, r2 / te);
83     }
84     return 0;
85 }
View Code
原文地址:https://www.cnblogs.com/luomi/p/5762337.html