[uva] 11205 - The broken pedometer

本文探讨了一种使用二进制枚举而非深度优先搜索(DFS)来解决子集问题的方法。通过枚举从0到2^P-1的所有二进制数,可以高效地生成所有可能的子集。作者分享了实现这一算法的过程,并提供了一个示例代码,包括初始化变量、读取输入数据、实现二进制枚举和输出结果的步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2146

这道题 我用dfs生成所有子集秒掉了, 但是, 末子大神给出了不用dfs的更快的方法, 枚举就行了, 膜拜= =待我想想

----补充----

今天苦于思索末子大神的算法, 最终找到几个反例, 感觉应该是不对的.

不过我在网上确实找到了不用dfs枚举的算法, 实际上核心就是P个二进制位组成的串, 他的所有子集, 其实就是二进制的0枚举到2^P-1. 待我晚上回家,把这个算法写一下.

 1 #include <cstdio>
 2 #include <vector>
 3 #include <bitset>
 4 #include <climits>
 5 #include <iostream>
 6 using namespace std;
 7 
 8 #define MAX 15
 9 
10 vector<bitset<MAX> > vec;
11 int P = 0;
12 int N = 0;
13 bitset<MAX> flag;
14 int minre = INT_MAX;
15 void dfs (int cur) {
16     if (cur == P) {
17         //cout<<flag<<endl;
18         bool f = true;
19         for (int i = 0; i < N; ++i) {
20             for (int j = i + 1; j < N; ++j) {
21                 bitset<MAX> l = vec[i];
22                 bitset<MAX> r = vec[j];
23                 l = l & flag;
24                 r = r & flag;
25                 if (l == r) {
26                     f = false;
27                 }
28             }
29         }
30         if (f) {
31             if (flag.count() < minre) {
32                 minre = flag.count();
33             }
34         }
35     } else {
36         flag[cur] = 0;
37         dfs(cur + 1);
38         flag[cur] = 1;
39         dfs(cur + 1);
40     }
41 }
42 
43 int main()
44 {
45     int T = 0;
46     scanf("%d", &T);
47     for (int i = 0; i < T; ++i) {
48         scanf("%d%d", &P, &N);
49         flag.reset();
50         vec.clear();
51         minre = INT_MAX;
52         for (int j = 0; j < N; ++j) {
53             bitset<MAX> t;
54             for (int k = 0; k < P; ++k) {
55                 int temp = 0;
56                 scanf("%d", &temp);
57                 t[k] = temp;
58             }
59             vec.push_back(t);
60         }
61     //    for (int i = 0; i < N; ++i) {
62             //cout<<vec[i]<<endl;
63     //    }
64         dfs(0);
65         printf("%d\n", minre);
66     } 
67     return 0;
68 }

 

 

转载于:https://www.cnblogs.com/NextLife/p/3446901.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值