※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 19576번 문제인 약수이다.
문제는 아래 링크를 확인하자.

https://www.acmicpc.net/problem/19576 

 

19576번: 약수

가능 한 방법 중 하나로, a2를 12로, a3을 3으로 바꾸면 된다. 

www.acmicpc.net

 

"와우매직"을 적용하지 않은 정수들은 서로 약수와 배수 관계에 있어야 함을 관찰하자. 그리고 "와우매직"을 적용할 때 각 미네랄 성분의 함량을 일괄적으로 1로 바꾼다면 항상 다른 모든 수와 약수와 배수 관계에 있게 됨을 관찰하자. 이와 같은 관찰에 따라 이 문제는 "서로 약수와 배수 관계에 있는 maximal한 집합"을 찾아 그 원소의 개수를 N에서 뺀 값을 구하는 것으로 해결할 수 있음을 알 수 있다.

한편, 어떤 주어진 정수들이 모든 쌍이 서로 약수와 배수의 관계를 이룬다면 해당 정수들을 오름차순으로 나열했을 때 먼저 등장하는 수는 항상 뒤에 등장하는 수의 약수가 되어야 함을 관찰하자. 이와 같은 관찰을 이용하면, 주어지는 N개의 수를 오름차순으로 정렬한 다음 '다음 항이 항상 이전 항의 배수인 부분수열'의 길이의 최댓값을 구하는 것으로 원하는 수의 집합을 구할 수 있음을 알 수 있다. 그 크기는 O(N2) DP로 어렵지 않게 구할 수 있다.

아래는 제출한 소스코드이다.

#include <iostream>
#include <algorithm>
using namespace std;

int N;
int A[5000];
int dp[5000], mx;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> N;
	for (int i = 0; i < N; i++) cin >> A[i];
	sort(A, A + N);

	for (int i = 0; i < N; i++) {
		mx = max(mx, dp[i]);
		for (int j = i + 1; j < N; j++) {
			if (A[j] % A[i]) continue;
			dp[j] = max(dp[j], dp[i] + 1);
		}
	}

	cout << N - (mx + 1);
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 16894 // C++] 약수 게임  (0) 2024.03.24
[BOJ 27505 // C++] 천국의 계단  (1) 2024.03.23
[BOJ 13343 // C++] Block Game  (0) 2024.03.21
[BOJ 14905 // C++] 소수 4개의 합  (0) 2024.03.20
[BOJ 11692 // C++] 시그마 함수  (3) 2024.03.19

+ Recent posts