백준의 보물(1026) 문제이다.
[ 문제 바로가기 ]
[ 문제풀이 ]
1) 두 개의 배열에서, A배열만 재배치를 해서 주어진 식의 최솟값을 찾는 문제이다.
그럼 직관적으로 생각을 해 봤을 때, A배열과 B배열의 동일한 Index값끼리 곱해서 더한 값이 최소가 되어야 하기 때문에
곱한 값이 최소가 되어버리면 당연히 더한 결과도 최솟값이 될 것이다.
그럼 곱해서 최소가 되려면 어떡해야할까 ?? 무조건 큰 값과 작은 값이 만나도록 만들어 주어야 한다.
큰 값과 큰 값이 만나면 당연히 그 결과값이 커질 것이고 , 큰 값과 작은 값이 만나면 그 값은 더 작아질 것이다.
즉, A배열을 오름차순으로, B배열을 내림차순으로 정렬 후 곱해서 더해버리면 된다.
그런데 B배열은 재배열 하면 안된다고 했는데 ??
우리는 결과값을 구하기 위해서 이렇게 정렬을 했을 뿐, B를 재배치 하지는 않았다고 볼 수 있다.
예제입력 1을 봐보자.
[ 1 , 1 , 1 , 6 , 0 ] , [ 2 , 7 , 8 , 3 , 1 ] 이 있을 때 이를 위와 같이 정렬 시켜보면
[ 0 , 1 , 1 , 1 , 6 ] , [ 8 , 7 , 3 , 2 , 1 ] 이 될 것이고 곱해서 더하면 18이 나오게 된다.
근데 B를 재배치 시켰잖아 ???
다르게 보면 다음과 같이 볼 수 있다.
B를 재배치 시키지 않고 [ 2 , 7 , 8 , 3 , 1 ] 로 두고, A배열을 [ 1 , 1 , 0 , 1 , 6 ] 으로 배치시켰다고 볼 수 있다.
즉, B를 재배치 시키면 안된다는 말이 있었지만 사실 정답을 출력하는데에는 아무런 지장이 없다.
[ 소스코드 ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #include<iostream> #include<algorithm> #define endl "\n" #define MAX 50 using namespace std; int N; int Arr_A[MAX]; int Arr_B[MAX]; bool Select[MAX]; void Input() { cin >> N; for (int i = 0; i < N; i++) cin >> Arr_A[i]; for (int i = 0; i < N; i++) cin >> Arr_B[i]; } bool Cmp(int A, int B) { if (A > B) return true; return false; } void Solution() { sort(Arr_A, Arr_A + N); sort(Arr_B, Arr_B + N, Cmp); int Sum = 0; for (int i = 0; i < N; i++) Sum = Sum + (Arr_A[i] * Arr_B[i]); cout << Sum << endl; } void Solve() { Input(); Solution(); } int main(void) { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); //freopen("Input.txt", "r", stdin); Solve(); return 0; } | cs |
'[ BOJ Code ] > # BOJ -' 카테고리의 다른 글
[ 백준 1520 ] 내리막길 (C++) (6) | 2020.02.21 |
---|---|
[ 백준 1103 ] 게임 (C++) (0) | 2020.02.20 |
[ 백준 15486 ] 퇴사2 (C++) (2) | 2020.02.19 |
[ 백준 15653 ] 구슬 탈출4 (C++) (0) | 2020.02.06 |
[ 백준 15644 ] 구슬 탈출3 (C++) (4) | 2020.02.04 |