백준 벡터 매칭(1007)
1. 힌트
1) 개의 점으로 이루어진 집합 에서 임의의 서로 다른 두 점 를 골랐을 때 와 를 끝점으로 하는 벡터는 개가 있고, 각각 좌표 성분으로 표기하면 혹은 가 된다.
2) 벡터의 합 연산은 좌표 성분으로 나타냈을 때 각각의 좌표 값을 더한 값이 됩니다. 또한 교환 법칙이 성립합니다.
3) 어차피 모든 점을 선택해야하므로 개의 좌표 성분을 모두 더하되, 그 중에서 개에는 음수를 붙여줘야 합니다. 이 경우를 모두 시도해볼 수 있습니다.
2. 접근
1) 단순한 방법에서 시작할 수 있을까?
무식한 방법으로 생각하면 개에서 개의 점의 순서쌍을 개 고르는 경우를 모두 시도하고 순서쌍의 순서를 바꾼 경우도 모두 고려해주면 바로 시간초과가 납니다. 벡터의 성질을 이용해서 더 간단하게 바꿀 수 없을까요?
2) 문제를 분해할 수 있을까?
개의 점으로 이루어진 집합 에서 임의의 서로 다른 두 점 를 골랐을 때 와 를 끝점으로 하는 벡터는 개가 있고, 각각 좌표 성분으로 표기하면 혹은 가 됩니다
최적해를 찾기 위해 우리가 고른 개의 벡터의 집합을 라고 해보겠습니다. 벡터의 합은 결국 또 다른 새로운 벡터인데 이는 각각의 좌표 성분을 모두 더하면 만들어 낼 수 있습니다. 그 벡터를 라고 해 보겠습니다
가 됩니다.
3) 문제를 단순화할 수 없을까?
의 원소 벡터들은 혹은 로 생각할 수 있는데, 연산의 순서가 상관이 없으므로 우리는 개의 정점에서 개의 음수를 고르면 를 만들어 낼 수 있다는 것을 알 수 있습니다.
또한 벡터의 성분이 주어져 있을 때 그 벡터의 크기는 으로 쉽게 구할 수 있습니다.
3. 구현
public class Main {
static int N;
static Pair[] P;
static boolean[] picked;
// P[here, N)에서 k개를 고르는 경우 모두 시도
static double bfc(int here, int k) {
if (here == N) {
if (k != 0) return Double.MAX_VALUE;
long y = 0; long x = 0;
for (int i = 0; i < N; i++) {
if (picked[i]) { y -= P[i].y; x -= P[i].x; }
else { y += P[i].y; x += P[i].x; }
}
return Math.sqrt(y * y + x * x);
}
double min = bfc(here + 1, k);
picked[here] = true;
min = Math.min(min, bfc(here + 1, k - 1));
picked[here] = false;
return min;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder bw = new StringBuilder();
int TC = Integer.parseInt(br.readLine());
while (TC-- > 0) {
N = Integer.parseInt(br.readLine());
P = new Pair[N];
picked = new boolean[N];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
P[i] = new Pair(Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()));
}
bw.append(bfc(0, N / 2)).append("\n");
}
System.out.print(bw);
}
}
class Pair {
int y, x;
Pair(int y, int x) { this.y = y; this.x = x; }
}
1) 시간 복잡도
개에서 개를 선택하는 경우를 모두 시도하므로 이 경우의 수는 최대 이 됩니다. 하지만 모든 원소마다 선택 하느나 하지 않느냐로 재귀 호출하므로 이 됩니다.
Author And Source
이 문제에 관하여(백준 벡터 매칭(1007)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@axiom0510/b1007저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)