[백준] 1965번 C/C++ 풀이 _ 상자넣기



출처 : https://www.acmicpc.net/problem/1965 

시간 제한메모리 제한제출정답맞은 사람정답 비율
2 초128 MB70633102249645.316%

문제

정육면체 모양의 상자들이 일렬로 늘어서 있다. 상자들마다 크기가 주어져 있는데, 앞에 있는 상자의 크기가 뒤에 있는 상자의 크기보다 작으면, 앞에 있는 상자를 뒤에 있는 상자 안에 넣을 수가 있다. 예를 들어 앞에서부터 순서대로 크기가 (1, 5, 2, 3, 7)인 5개의 상자가 있다면, 크기 1인 상자를 크기 5인 상자에 넣고, 다시 이 상자들을 크기 7인 상자 안에 넣을 수 있다. 하지만 이렇게 상자를 넣을 수 있는 방법은 여러 가지가 있을 수 있다. 앞의 예에서 차례대로 크기가 1, 2, 3, 7인 상자들을 선택하면 총 4개의 상자가 한 개의 상자에 들어가게 된다.

상자들의 크기가 주어질 때, 한 번에 넣을 수 있는 최대의 상자 개수를 출력하는 프로그램을 작성하시오.

입력

파일의 첫 번째 줄은 상자의 개수 n (1≤n ≤1000)을 나타낸다. 두 번째 줄에는 각 상자들의 크기가 순서대로 주어진다.

출력

첫째 줄에 한 줄에 넣을 수 있는 최대의 상자 개수를 출력한다.

예제 입력 1 

8
1 6 2 5 7 3 5 6

예제 출력 1 

5

출처

  • 잘못된 데이터를 찾은 사람: tncks0121

풀이 

저는 이 문제의 풀이를 LIS 를 이용하여 풀었습니다. 

lower_bound 에 대한 설명은 http://blockdmask.tistory.com/168 를 참조하시면 좋습니다.
lower_bound 는 벡터나 배열이 정렬되어 있는 상태에서,
이진 탐색을 이용하여 찾으려는 수 이상의 숫자가 나오는 최초의 인덱스를 리턴합니다. 

http://jason9319.tistory.com/113 
http://seungkwan.tistory.com/8
위의 두 링크를 참조해보면 쉽게 이해하실 수 있습니다. 

해당 풀이를 아래의 소스코드로 구현해보았습니다. 

https://m.blog.naver.com/PostView.nhn?blogId=occidere&logNo=220788208204&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F 

위의 링크는 lower_bound 를 쓰지 않은 풀이입니다. 

소스코드

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
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std
#pragma warning(disable:4996)
#define INF 987654321
int main() {
    int n; scanf("%d"&n);
    vector<int> num_vec(n + 1987654321), ascend_vec;
    for (int n_idx = 1; n_idx <= n; n_idx++)
        scanf("%d"&num_vec[n_idx]);
    
    int n_idx = 1;
    ascend_vec.push_back(num_vec[n_idx++]);
    for (n_idx = 2; n_idx <= n; n_idx++){
        auto idx = lower_bound(ascend_vec.begin(), ascend_vec.end(), num_vec[n_idx]);
        // 현재 벡터에서 가장 큰 수보다 더 크면, 삽입
        if (idx == ascend_vec.end())
            ascend_vec.push_back(num_vec[n_idx]);
        // 현재 벡터에서 가장 큰 수보다 적으면, 
        // 해당 숫자보다 큰 요소들 중 가장 작은 요소 대신에 삽입 
        else
            *idx = num_vec[n_idx];
    }
    printf("%d", ascend_vec.size());
    return 0;
}
cs