반응형

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

 

3066번: 브리징 시그널

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 첫 번째 줄에 포트의 개수 N(1 ≤ N ≤ 40000)이 주어지고, 두 번째 줄부터는 왼쪽 블록의 포트와 연결되어야 하는 오른쪽

www.acmicpc.net

 

 

[ 문제풀이 ]

 

이 문제를 풀기 전에 다음 글을 먼저 읽고 오시는 것을 추천드립니다.

https://rudalsd.tistory.com/175

 

[ 알고리즘 ] 최장 증가 부분 수열(Longest Increasing Subsequence)

1. 최장 증가 부분 수열(Longest Increasing Subsequence)이란? 어떠한 수열이 주어질 때, 그 수열에서 일부 원소를 뽑아내어 새로 만든 수열을 '부분 수열'이라고 하며, 이 수열이 오름차순을 유지하면 '증

rudalsd.tistory.com

 

1. arr 배열을 만들어서 입력받은 포트 번호를 저장합니다.

 

2. lower_bound를 이용하여 LIS의 길이를 구하고, LIS.size()를 출력합니다.

 

[ 소스코드 ]

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
#include<iostream>
#include<vector>
#include<algorithm>
 
using namespace std;
 
int arr[40000];
 
int main()
{
    int T;
    scanf("%d"&T);
 
    for (int t = 0; t < T; t++) {
        int N;
        scanf("%d"&N);
 
        for (int i = 0; i < N; i++) {
            scanf("%d"&arr[i]);
        }
 
        vector<int> LIS;
        LIS.push_back(arr[0]);
 
        for (int i = 1; i < N; i++) {
            if (LIS[LIS.size() - 1< arr[i]) {
                LIS.push_back(arr[i]);
            }
            else {
                auto it = lower_bound(LIS.begin(), LIS.end(), arr[i]);
                *it = arr[i];
            }
        }
 
        printf("%d\n", (int)LIS.size());
    }
}
cs
반응형
반응형

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

 

2565번: 전깃줄

첫째 줄에는 두 전봇대 사이의 전깃줄의 개수가 주어진다. 전깃줄의 개수는 100 이하의 자연수이다. 둘째 줄부터 한 줄에 하나씩 전깃줄이 A전봇대와 연결되는 위치의 번호와 B전봇대와 연결되는

www.acmicpc.net

 

 

[ 문제풀이 ]

 

이 문제를 풀기 전에 다음 글을 먼저 읽고 오시는 것을 추천드립니다.

https://rudalsd.tistory.com/175

 

[ 알고리즘 ] 최장 증가 부분 수열(Longest Increasing Subsequence)

1. 최장 증가 부분 수열(Longest Increasing Subsequence)이란? 어떠한 수열이 주어질 때, 그 수열에서 일부 원소를 뽑아내어 새로 만든 수열을 '부분 수열'이라고 하며, 이 수열이 오름차순을 유지하면 '증

rudalsd.tistory.com

 

1. pair<int, int> arr 배열을 만들어서 입력받은 A전봇대와 B전봇대를 저장합니다.

 

2. A전봇대의 번호를 기준으로 오름차순으로 정렬합니다.

 

3. lower_bound를 이용하여 LIS의 길이를 구하고, N - LIS.size()를 출력합니다.

 

[ 소스코드 ]

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
#include<iostream>
#include<vector>
#include<algorithm>
 
using namespace std;
 
int N;
vector<int> LIS;
pair<intint> arr[100];
 
int main()
{
    scanf("%d"&N);
 
    for (int i = 0; i < N; i++) {
        int A, B;
        scanf("%d %d"&A, &B);
        arr[i] = { A,B };
    }
 
    sort(arr, arr + N);
 
    LIS.push_back(arr[0].second);
 
    for (int i = 1; i < N; i++) {
        if (LIS[LIS.size() - 1< arr[i].second) {
            LIS.push_back(arr[i].second);
        }
        else {
            auto it = lower_bound(LIS.begin(), LIS.end(), arr[i].second);
            *it = arr[i].second;
        }
    }
 
    printf("%d", N - (int)LIS.size());
}
cs
반응형
반응형

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

 

3745번: 오름세

입력은 여러개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 주가를 관찰한 날의 수 N (N ≤ 100000)이 주어진다. 둘째 줄에는 관찰한 주가가 첫 날부터 순서대로 주어진다.

www.acmicpc.net

 

 

[ 문제풀이 ]

 

이 문제를 풀기 전에 다음 글을 먼저 읽고 오시는 것을 추천드립니다!

https://rudalsd.tistory.com/175

 

[ 알고리즘 ] 최장 증가 부분 수열(Longest Increasing Subsequence)

1. 최장 증가 부분 수열(Longest Increasing Subsequence)이란? 어떠한 수열이 주어질 때, 그 수열에서 일부 원소를 뽑아내어 새로 만든 수열을 '부분 수열'이라고 하며, 이 수열이 오름차순을 유지하면 '증

rudalsd.tistory.com

 

1. lower_bound를 활용하여 LIS의 길이를 구합니다.

 

2. LIS.size()를 출력합니다.

 

3. n을 입력받는 scanf의 반환값이 1이 아닐 때 break로 나와줍니다.

 

[ 소스코드 ]

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
#include<iostream>
#include<vector>
#include<algorithm>
 
using namespace std;
 
int main()
{
    while (1) {
        int n;
        vector<int> LIS;
        if (scanf("%d"&n) != 1) {
            break;
        }
        
        int num;
        scanf("%d"&num);
 
        LIS.push_back(num);
 
        for (int i = 1; i < n; i++) {
            scanf("%d"&num);
            if (LIS[LIS.size() - 1< num) {
                LIS.push_back(num);
            }
            else {
                auto idx = lower_bound(LIS.begin(), LIS.end(), num);
                *idx = num;
            }
        }
 
        printf("%d\n", LIS.size());
    }
}
cs
반응형
반응형

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

 

1818번: 책정리

동혁이는 캠프가 끝나고 집에 가서 책꽂이 정리를 하고 있었다. 책들은 한 줄로 길게 꽂히 있었다. 동혁이의 책은 1번부터 N번까지 숫자로 표현되고  현재 뒤죽박죽 되어있는 순서를 왼쪽부터

www.acmicpc.net

 

 

[ 문제풀이 ]

 

이 문제를 풀기 전에 다음 글을 먼저 읽고 오시는 것을 추천드립니다!

https://rudalsd.tistory.com/175

 

[ 알고리즘 ] 최장 증가 부분 수열(Longest Increasing Subsequence)

1. 최장 증가 부분 수열(Longest Increasing Subsequence)이란? 어떠한 수열이 주어질 때, 그 수열에서 일부 원소를 뽑아내어 새로 만든 수열을 '부분 수열'이라고 하며, 이 수열이 오름차순을 유지하면 '증

rudalsd.tistory.com

 

1. lower_bound를 활용하여 LIS의 길이를 구합니다.

 

2. N - LIS.size()를 출력합니다.

 

[ 소스코드 ]

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
#include<iostream>
#include<algorithm>
#include<vector>
 
using namespace std;
 
int N;
vector<int> LIS;
 
int main()
{
    scanf("%d"&N);
 
    int num;
 
    scanf("%d"&num);
 
    LIS.push_back(num);
 
    for (int i = 1; i < N; i++) {
        scanf("%d"&num);
 
        if (LIS[LIS.size() - 1< num) {
            LIS.push_back(num);
        }
        else {
            auto idx = lower_bound(LIS.begin(), LIS.end(), num);
            *idx = num;
        }
    }
 
    printf("%d", N - LIS.size());
}
cs
반응형
반응형

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

 

12014번: 주식

입력 파일에는 여러 테스트 케이스가 포함될 수 있다. 파일의 첫째 줄에 케이스의 개수 T(2 ≤ T ≤ 100)가 주어지고, 이후 차례로 T 개 테스트 케이스가 주어진다. 각 테스트 케이스의 첫 줄에 두

www.acmicpc.net

 

 

[ 문제풀이 ]

 

이 문제를 풀기 전에 다음 글을 먼저 읽고 오시는 것을 추천드립니다!

https://rudalsd.tistory.com/175

 

[ 알고리즘 ] 최장 증가 부분 수열(Longest Increasing Subsequence)

1. 최장 증가 부분 수열(Longest Increasing Subsequence)이란? 어떠한 수열이 주어질 때, 그 수열에서 일부 원소를 뽑아내어 새로 만든 수열을 '부분 수열'이라고 하며, 이 수열이 오름차순을 유지하면 '증

rudalsd.tistory.com

 

1. lower_bound를 활용하여 LIS의 길이를 구합니다.

 

2. LIS의 길이가 K보다 크거나 같다면 1, 아니라면 0을 출력합니다.

 

[ 소스코드 ]

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
#include<iostream>
#include<vector>
#include<algorithm>
 
using namespace std;
 
int main()
{
    int T;
    scanf("%d"&T);
 
    for (int t = 1; t <= T; t++) {
        int N, K;
        int num;
        vector<int> LIS;
 
        scanf("%d %d"&N, &K);
 
        scanf("%d"&num);
 
        LIS.push_back(num);
 
        for (int i = 1; i < N; i++) {
            scanf("%d"&num);
            if (LIS[LIS.size() - 1< num) {
                LIS.push_back(num);
            }
            else {
                auto idx = lower_bound(LIS.begin(), LIS.end(), num);
                *idx = num;
            }
        }
 
        printf("Case #%d\n", t);
 
        if (LIS.size() >= K) {
            printf("1\n");
        }
        else {
            printf("0\n");
        }
    }
}
cs
반응형
반응형

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

 

1365번: 꼬인 전깃줄

첫 줄에 전봇대의 개수 N(1 ≤ N ≤ 100,000)이 주어지고, 이어서 N보다 작거나 같은 자연수가 N개 주어진다. i번째 줄에 입력되는 자연수는 길 왼쪽에 i번째 전봇대와 연결된 길 오른편의 전봇대가

www.acmicpc.net

 

 

[ 문제풀이 ]

 

이 문제를 풀기 전에 다음 글을 먼저 읽고 오시는 것을 추천드립니다!

https://rudalsd.tistory.com/175

 

[ 알고리즘 ] 최장 증가 부분 수열(Longest Increasing Subsequence)

1. 최장 증가 부분 수열(Longest Increasing Subsequence)이란? 어떠한 수열이 주어질 때, 그 수열에서 일부 원소를 뽑아내어 새로 만든 수열을 '부분 수열'이라고 하며, 이 수열이 오름차순을 유지하면 '증

rudalsd.tistory.com

 

1. lower_bound를 활용하여 LIS의 길이를 구합니다.

 

2. N - LIS.size()를 출력합니다.

 

[ 소스코드 ]

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
#include<iostream>
#include<vector>
#include<algorithm>
 
using namespace std;
 
int N;
int arr[100000];
vector<int> LIS;
 
//int lower_bound(vector<int> vect, int num)
//{
//    int lo = -1;
//    int hi = vect.size() - 1;
//
//    while (lo + 1 < hi) {
//        int mid = (lo + hi) / 2;
//        if (vect[mid] < num) {
//            lo = mid;
//        }
//        else {
//            hi = mid;
//        }
//    }
//
//    return hi;
//}
 
int main()
{
    scanf("%d"&N);
 
    for (int i = 0; i < N; i++) {
        scanf("%d"&arr[i]);
    }
 
    LIS.push_back(arr[0]);
 
    for (int i = 1; i < N; i++) {
        if (LIS[LIS.size() - 1< arr[i]) {
            LIS.push_back(arr[i]);
        }
        else {
            auto idx = lower_bound(LIS.begin(), LIS.end(), arr[i]);
            *idx = arr[i];
        }
    }
 
    printf("%d", N - LIS.size());
}
cs
반응형

'백준' 카테고리의 다른 글

[ 백준 ] 6593번 - 상범 빌딩 (C++)  (0) 2022.12.18
[ 백준 ] 12014번 - 주식 (C++)  (0) 2022.12.17
[ 백준 ] 16397번 - 탈출 (C++)  (0) 2022.12.15
[ 백준 ] 2812번 - 크게 만들기 (C++)  (0) 2022.12.14
[ 백준 ] 9019번 - DSLR (C++)  (0) 2022.12.13
반응형

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

 

2550번: 전구

N개의 스위치와 N개의 전구를 가진 하나의 스위칭 박스가 있다. 이 박스의 왼편에는 스위치가 있고, 오른편에는 전구가 달려있다. 모든 스위치와 전구들은 1에서부터 N까지의 번호를 가지며 같은

www.acmicpc.net

 

 

[ 문제풀이 ]

 

글을 읽기 전에 다음 글을 먼저 읽고 오시는 것을 추천드립니다!

https://rudalsd.tistory.com/175

 

[ 알고리즘 ] 최장 증가 부분 수열(Longest Increasing Subsequence)

1. 최장 증가 부분 수열(Longest Increasing Subsequence)이란? 어떠한 수열이 주어질 때, 그 수열에서 일부 원소를 뽑아내어 새로 만든 수열을 '부분 수열'이라고 하며, 이 수열이 오름차순을 유지하면 '증

rudalsd.tistory.com

 

1. 스위치를 순서대로 저장할 배열과 스위치의 위치를 저장할 배열을 각각 만들어 값을 저장합니다.

 

2. 전구의 위치를 저장할 배열을 만들어 값을 저장합니다.

 

3. lower_bound를 이용해 LIS를 만들고, 각각의 스위치가 LIS에서 몇 번째 idx에 있는지 idx 배열을 만들어 값을 저장합니다.

 

4. idx 배열의 끝에서부터 for문을 돌면서 LIS에 들어갈 스위치를 ans 배열에 저장합니다.

 

5. ans 배열을 정렬합니다.

 

6. LIS의 size를 출력하고, ans에 저장된 값을 하나씩 출력합니다.

 

[ 소스코드 ]

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
53
54
55
56
57
58
59
60
61
62
63
#include<iostream>
#include<algorithm>
#include<vector>
 
using namespace std;
 
int N;
int sw[10001];        //sw[i] = 스위치 번호
int pos[10001];        //pos[스위치 번호] = i
int bulb[10001];    //전구의 순서
int idx[10001];        //LIS에서 몇번 째 위치해 있는지 저장할 배열
vector<int> LIS;
vector<int> ans;
 
int main()
{
    scanf("%d"&N);
 
    for (int i = 0; i < N; i++) {
        int idx;
        scanf("%d"&idx);
        sw[i] = idx;
        pos[idx] = i;
    }
 
    for (int i = 0; i < N; i++) {
        int idx;
        scanf("%d"&idx);
        bulb[pos[idx]] = i;
    }
 
    LIS.push_back(bulb[0]);
    idx[0= 1;
 
    for (int i = 1; i < N; i++) {        //lower_bound
        if (bulb[i] > LIS[LIS.size() - 1]) {
            LIS.push_back(bulb[i]);
            idx[i] = LIS.size();
        }
        else {
            auto it = lower_bound(LIS.begin(), LIS.end(), bulb[i]);
            *it = bulb[i];
            idx[i] = it - LIS.begin() + 1;    //현재 스위치의 LIS에서의 위치
        }
    }
 
    int cur = LIS.size();
 
    for (int i = N - 1; i >= 0; i--) {
        if (idx[i] == cur) {
            ans.push_back(sw[i]);
            cur--;
        }
    }
 
    sort(ans.begin(), ans.end());
 
    printf("%d\n", LIS.size());
 
    for (int i = 0; i < LIS.size(); i++) {
        printf("%d ", ans[i]);
    }
}
cs
반응형
반응형

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

 

1965번: 상자넣기

정육면체 모양의 상자가 일렬로 늘어서 있다. 상자마다 크기가 주어져 있는데, 앞에 있는 상자의 크기가 뒤에 있는 상자의 크기보다 작으면, 앞에 있는 상자를 뒤에 있는 상자 안에 넣을 수가

www.acmicpc.net

 

 

[ 문제풀이 ]

 

이 문제를 풀기 전에 다음 글을 먼저 읽고 오시는 것을 추천드립니다.

https://rudalsd.tistory.com/175?category=1064608 

 

[ 알고리즘 ] 최장 증가 부분 수열(Longest Increasing Subsequence)

1. 최장 증가 부분 수열(Longest Increasing Subsequence)이란? 어떠한 수열이 주어질 때, 그 수열에서 일부 원소를 뽑아내어 새로 만든 수열을 '부분 수열'이라고 하며, 이 수열이 오름차순을 유지하면

rudalsd.tistory.com

 

1. LIS를 구합니다.

 

2. LIS의 길이를 출력합니다.

 

[ 소스코드 ]

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
#include<iostream>
#include<vector>
#include<algorithm>
 
using namespace std;
 
int N;
 
int main()
{
    vector<int> LIS;
 
    scanf("%d"&N);
 
    for (int i = 0; i < N; i++) {
        int num;
        scanf("%d"&num);
        if (i == 0) {
            LIS.push_back(num);
        }
        else {
            if (LIS[LIS.size() - 1< num) {
                LIS.push_back(num);
            }
            else {
                auto idx = lower_bound(LIS.begin(), LIS.end(), num);
                *idx = num;
            }
        }
    }
 
    printf("%d", LIS.size());
}
cs
반응형
반응형

1. 최장 증가 부분 수열(Longest Increasing Subsequence)이란?

 

어떠한 수열이 주어질 때, 그 수열에서 일부 원소를 뽑아내어 새로 만든 수열을 '부분 수열'이라고 하며, 이 수열이 오름차순을 유지하면 '증가하는 부분 수열'이 되는 것이다. 최장 증가 부분 수열(Longest Increasing Subsequence)이란 '증가하는 부분 수열' 중 가장 긴 수열을 의미합니다.

 

2. 최장 증가 부분 수열(Longest Increasing Subsequence)동작 원리

 

O(NlogN)의 시간복잡도가 걸리는 lower_bound를 활용하여 구할 수 있습니다.

 

1 2 3 5 6      

위와 같은 수열을 예로 들어서 설명드리겠습니다.

 

수열의 첫 수를 LIS에 넣어줍니다.

LIS의 마지막 수보다 현재 숫자가 더 크다면 LIS에 넣어줍니다.

그렇지 않다면 lower_bound를 활용해 현재 수보다 크거나 같은 수가 있는 곳의 index의 값을 현재 수로 바꿔줍니다.

위와 같은 방식으로 LIS를 채워주면 다음과 같은 결과를 얻을 수 있습니다.

 

유의할 점은 위의 방식으로 LIS를 구하면 길이는 구할 수 있지만 부분수열 자체는 구할 수 없습니다.

반응형

+ Recent posts