-
[알고리즘 문제 풀이][비트마스킹] 백준 23630번 - 가장 긴 부분 수열 구하기자료구조&알고리즘/알고리즘 - 대회 알고리즘 2024. 11. 24. 15:48
풀이 참고 블로그: [Python] 23630번 가장 긴 부분 수열 구하기
- 문제 설명: 23630번: 가장 긴 부분 수열 구하기
N개의 자연수로 이루어진 수열 A = {A1, A2, ..., AN} 이 주어집니다.
다음 조건을 만족하는 가장 긴 부분 수열을 찾아야합니다.
(1) Ai1 & Ai2 & ... & Aim 이 0 이 아니어야 합니다. (선택한 수들끼리 AND 비트 연산을 했을 때 겹치는 비트가 1개 이상이 있어야합니다.)
(2) 1 <= i1 < i2 < ... < im <=N 이어야합니다. (A 내에서 수를 선택할 때 겹치지 않게 순서대로 하나씩 선택해야합니다.)
N 의 최대 크기는 1,000,000 이며, Ai 의 최대 수 또한 1,000,000입니다.
- 문제 풀이:
조건을 만족하는 가장 긴 부분 수열을 찾는다고 하면, 백트래킹을 먼저 생각해볼 수 있습니다.
하지만, N이 1,000,000 이기 때문에 이 크기의 수열을 백트래킹을 한다고 하면 시간 초과를 피할 수 없습니다.
따라서 시간 안에 들어올 수 있는 다른 측면의 해답이 필요합니다.
Ai 의 최대값이 1,000,000 이기 때문에 비트로 표현하면 2^20 (=1,048,576) 안에 표현할 수 있습니다.
19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 문제의 조건 (1) 을 만족하려면 겹치는 비트가 있어야하는데, 0~19번째 비트 중에서 수들 간에 가장 많이 겹치는 비트를 찾으면 그 수들을 선택했을 때 정답이 될 것입니다.
따라서 각 수마다 0번~19번 비트 중에 어떤 비트를 가지고 있는지를 세고, 최종적으로 0번~19번 비트마다 수열의 수들이 가장 많이 공통적으로 갖고 있는 비트를 출력합니다.
- 코드 (Python):
n=int(input()) a=list(map(int,input().split())) cnt=[0]*20 for i in range(n): for j in range(20): if a[i]&(1<<j): cnt[j]+=1 ans=0 for i in range(20): if ans<cnt[i]: ans=cnt[i] print(ans)
- 실수 포인트 & 반례:
문제의 예제 외에 필요한 반례는 없었습니다
'자료구조&알고리즘 > 알고리즘 - 대회 알고리즘' 카테고리의 다른 글
[알고리즘 문제 풀이][Union-Find] 백준 13383번 - Oil (0) 2024.08.28 [알고리즘 문제 풀이][수학] 백준 23364번 - Almost Always (0) 2024.07.15 백준 2545 팬케익 먹기 증명 (라그랑주 승수법) (0) 2024.04.04 [알고리즘 문제 풀이][그리디] 백준 3211번 - kino (0) 2024.02.01 [알고리즘 문제 풀이][기하학] 백준 16483번 - 접시 안의 원 (0) 2023.02.11 댓글