모든 집합의 합집합과 다르게 되는 일부를 골라 만든 최대 합집합
s1,s2,...,sn 집합이 주어질때, 이들 중 일부를 골라 만든 합집합 s와 모든 집합의 합집합 s1 ∪ s2 ∪ ... ∪ sn이
서로 다르게 되는 가장 큰 합집합 s를 구하고 싶다
집합을 기준으로 s1 넣어보고 s2는 넣지말고... sn은 넣고 등등으로 해서 s를 다 조사해보는건 $O(2^{50})$으로 어렵다
모든 집합의 합집합을 먼저 구하고 그 중에서 하나의 집합만 빼는 방법은 어떨까?
집합 합칠수록 원소가 많아질테니까...
s2 ∪ s3 ∪ ... ∪ sn
s1 ∪ s3 ∪ ... ∪ sn
...
이러면 O(N)정도니까 괜찮을것 같은데
[1], [3,6,10], [9], [1,3], [5,8,9]를 보면
모든 집합의 합집합은 [1,3,5,6,8,9,10]
집합 하나만 빼서 해본다면
[1,3,5,6,8,9,10]
[1,3,5,8,9]
[1,3,5,6,8,9,10]
[1,3,5,6,8,9,10]
[1,3,6,9,10]
으로 5개가 최대인데
사실 [3,6,10]과 [5,8,9]의 합집합으로 [3,5,6,8,9,10]으로 6개가 최대이게 만들 수 있다
--------------------------------------------------------------------------------------------------------------------------------------------
그렇다면 모든 집합의 합집합 [1,3,5,6,8,9,10]에서 각각의 원소가 들어가지 않은 집합들의 합집합을 비교하는건 어떨까?
s1,s2,...,sn중 1이 들어가지 않은 집합을 모두 고른 다음 합집합을 구해보고
3이 들어가지 않은 집합을 모두 골라 합집합을 구해보고
5가 들어가지 않은 집합을 모두 골라 합집합을 구해보고...
...
10이 들어가지 않은 집합을 모두 골라 합집합을 구해본다면?
모든 집합의 합집합의 원소의 개수는 많아야 2500개라 충분히 할만하다
from sys import stdin
t = int(stdin.readline())
for _ in range(t):
n = int(stdin.readline())
S = []
for _ in range(n):
A = list(map(int,stdin.readline().split()))
k = A[0]
A = A[1:]
S.append(set(A))
#모든 집합들의 합집합 X
X = set()
for s in S:
for i in s:
X.add(i)
answer = 0
#X의 한 원소 x에 대하여
for x in X:
#s1,s2,..,sn중 x가 들어가지 않은 집합을 고르고
A = []
for s in S:
if x not in s:
A.append(s)
#x가 들어가지 않은 집합의 합집합을 구한 다음
B = set()
for a in A:
for i in a:
B.add(i)
#x가 들어가지 않은 집합의 합집합들 중 최대 크기를 찾는다
if answer < len(B):
answer = len(B)
print(answer)
'알고리즘 > 브루트포스' 카테고리의 다른 글
좌표들이 주어질때 좌표간 간격이 될 수 있는 모든 수를 찾는 방법 (0) | 2024.09.24 |
---|---|
그래프에서 서로 연결된 세 정점의 차수 합의 최솟값 찾기 (0) | 2024.09.10 |
생각해서 브루트포스 탐색 범위를 줄여야하는 경우1 (장난감 강아지) (0) | 2024.02.03 |
잊을만하면 순열조합 연습하기 -치킨배달- (0) | 2022.10.30 |
완전탐색 순열과 조합 연습장2 -앞자리에 0이 못오게 하기- (0) | 2022.10.30 |