思路:当N>1时,假设存在这样一个子集符合要求,那么肯定存在其中的<=2个元素也能符合要求。证明:对于属性1,从K1=1和K1=0的集合里各取一个数,有(n/2)^2种组合,那么K2最坏的情况能破坏其中的(n/4)^2种组合,K3,K4亦然,那么有(n/2)^2 > 3*((n/4)^2),这里的除法是下取整。所以总能找到2个元素符合要求。题目K<=4,至多有(1<<4)-1种情况,暴力一下就行了。
# include <iostream>
# include <cstdio>
# include <algorithm>
using namespace std;
int vis[1<<4], a[40];
int main()
{
int n, k, m, cnt=0;
scanf("%d%d",&n,&k);
for(int i=0; i<n; ++i)
{
int num = 0;
for(int j=0; j<k; ++j)
{
scanf("%d",&m);
num = num<<1|m;
}
if(!num) return 0*puts("YES");
if(++vis[num] == 1) a[cnt++] = num;
}
for(int i=0; i<cnt; ++i)
for(int j=i+1; j<cnt; ++j)
if((a[i]&a[j]) == 0)
return 0*puts("YES");
puts("NO");
return 0;
}