dfs递归枚举所有的子集,检验每一个子集是否能够使得每一个数字的编码不同,如果发现这样的子集,就统计其中1的个数,将结果更新为当前结果和前面统计出的1的个数的较小值,递归枚举结束后,得到的全局变量result就是最后的结果。
#include <stdio.h>
#include <math.h>
#include <vector>
#include <set>
using namespace std;
vector<int> original_code;
int arr[16];
int result;
void dfs(int len, int cur)
{
if(cur == len)
{
int mask, i, j, new_code;
set<int> last_code;
int one_count;
mask = 0;
for(i=0; i<len; i++)
{
if(arr[i])
mask += (int)pow(2.0, i);
}
last_code.clear();
for(i=0; i<original_code.size(); i++)
{
new_code = mask&original_code[i];
if(last_code.find(new_code) != last_code.end())
break;
else
last_code.insert(new_code);
}
if(i == original_code.size())
{
//统计1的个数
one_count = 0;
for(j=0; j<len; j++)
if(arr[j])
one_count++;
if(one_count < result)
result = one_count;
}
return;
}
arr[cur] = 0;
dfs(len, cur+1);
arr[cur] = 1;
dfs(len, cur+1);
}
void func(int m, int n)
{
double r;
//递归生成子集
result = m;
dfs(m, 0);
printf("%d\n", result);
}
int main(void)
{
int m, n;
int data, sum;
int i, j;
int N;
//freopen("input.dat", "r", stdin);
scanf("%d", &N);
while(N--)
{
scanf("%d %d", &m, &n);
original_code.clear();
for(i=1; i<=n; i++)
{
sum = 0;
for(j=0; j<m; j++)
{
scanf("%d", &data);
if(data) sum += (int)pow(2.0, j);
}
original_code.push_back(sum);
}
func(m, n);
}
return 0;
}
本文介绍了一种使用递归枚举的方法来寻找所有子集,并通过编码比较来筛选出满足特定条件的子集,最终统计并输出满足条件的子集中1的最小个数。

3455

被折叠的 条评论
为什么被折叠?



