深搜就行了,注意剪枝。
ac 60ms
#include<iostream>
#include<algorithm>
#include<string.h>
#include<cmath>
using namespace std;
int P, N, ans;
int seq[100][15], c[15], vis[15], Min;
int judge(int num)
{
for (int i = 0; i < N - 1; i++)
{
for (int j = i + 1; j < N; j++)
{
int ok = 0;
for (int k = 0; k < num; k++)
{
if (seq[i][c[k]] != seq[j][c[k]])
{
ok = 1;
break;
}
}
if (ok == 0)
return 0;
}
}
return 1;
}
int dfs(int cur)
{
if (cur >= Min && judge(cur))
{
if (ans > cur)
ans = cur;
}
if (cur == P - 1)
return 0;
for (int i = 0; i < P; i++)
{
c[cur] = i;
int ok = 0;
for (int j = 0; j < cur; j++)
{
if (c[j] >= i)
{
ok = 1;
break;
}
}
if (ok)
continue;
dfs(cur + 1);
}
return 0;
}
int main()
{
int num;
cin >> num;
while (num--)
{
memset(c, 0, sizeof(c));
memset(seq, 0, sizeof(seq));
memset(vis, 0, sizeof(vis));
cin >> P >> N;
Min = log(N) / log(2);
ans = P;
for (int i = 0; i < N; i++)
for (int j = 0; j < P; j++)
scanf("%d", &seq[i][j]);
if (N == 1)
cout << 0 << endl;
else
{
dfs(0);
cout << ans << endl;
}
}
return 0;
}