๐Ÿ•๏ธ ICPC Sinchon/Binary Search

[BOJ][C++] ๋ฐฑ์ค€ 1365๋ฒˆ: ๊ผฌ์ธ ์ „๊นƒ์ค„

์„ ๋‹ฌ 2024. 9. 30. 19:28
๋ฐ˜์‘ํ˜•

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

 

๋ฌธ์ œ

๊ณตํ™”๊ตญ์— ์žˆ๋Š” ์œ ์Šคํƒ€์šด ์‹œ์—์„œ๋Š” ๊ธธ์„ ์‚ฌ์ด์— ๋‘๊ณ  ์ „๋ด‡๋Œ€๊ฐ€ ์•„๋ž˜์™€ ๊ฐ™์ด ๋‘ ์ค„๋กœ ๋Š˜์–ด์„œ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ธธ ์™ผํŽธ๊ณผ ๊ธธ ์˜ค๋ฅธํŽธ์˜ ์ „๋ด‡๋Œ€๋Š” ํ•˜๋‚˜์˜ ์ „์„ ์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค. ์–ด๋–ค ์ „๋ด‡๋Œ€๋„ ๋‘ ๊ฐœ ์ด์ƒ์˜ ๋‹ค๋ฅธ ์ „๋ด‡๋Œ€์™€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€๋Š” ์•Š๋‹ค.

๋ฌธ์ œ๋Š” ์ด ๋‘ ์ „๋ด‡๋Œ€ ์‚ฌ์ด์— ์žˆ๋Š” ์ „๊นƒ์ค„์ด ๋งค์šฐ ๊ผฌ์—ฌ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค. ๊ผฌ์—ฌ์žˆ๋Š” ์ „๊นƒ์ค„์€ ํ™”์žฌ๋ฅผ ์œ ๋ฐœํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ ์Šคํƒ€์šด ์‹œ์˜ ์‹œ์žฅ ์ž„ํ•œ์ˆ˜๋Š” ์ „๊ฒฉ์ ์œผ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

์ž„ํ•œ์ˆ˜๋Š” ๊ผฌ์—ฌ ์žˆ๋Š” ์ „๊นƒ์ค„ ์ค‘ ๋ช‡ ๊ฐœ๋ฅผ ์ ์ ˆํžˆ ์ž˜๋ผ ๋‚ด์–ด ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ฏธ ์„ค์น˜ํ•ด ๋†“์€ ์ „์„ ์ด ์•„๊น๊ธฐ ๋•Œ๋ฌธ์— ์ž˜๋ผ๋‚ด๋Š” ์ „์„ ์„ ์ตœ์†Œ๋กœ ํ•˜์—ฌ ๊ผฌ์—ฌ ์žˆ๋Š” ์ „์„ ์ด ํ•˜๋‚˜๋„ ์—†๊ฒŒ ๋งŒ๋“ค๋ ค๊ณ  ํ•œ๋‹ค.

์œ ์Šคํƒ€์šด ์‹œ์˜ ์‹œ์žฅ ์ž„ํ•œ์ˆ˜๋ฅผ ๋„์™€ ์ž˜๋ผ๋‚ด์•ผ ํ•  ์ „์„ ์˜ ์ตœ์†Œ ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

์ž…๋ ฅ

์ฒซ ์ค„์— ์ „๋ด‡๋Œ€์˜ ๊ฐœ์ˆ˜ N(1 ≤ N ≤ 100,000)์ด ์ฃผ์–ด์ง€๊ณ , ์ด์–ด์„œ N๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์ž์—ฐ์ˆ˜๊ฐ€ N๊ฐœ ์ฃผ์–ด์ง„๋‹ค. i๋ฒˆ์งธ ์ค„์— ์ž…๋ ฅ๋˜๋Š” ์ž์—ฐ์ˆ˜๋Š” ๊ธธ ์™ผ์ชฝ์— i๋ฒˆ์งธ ์ „๋ด‡๋Œ€์™€ ์—ฐ๊ฒฐ๋œ ๊ธธ ์˜ค๋ฅธํŽธ์˜ ์ „๋ด‡๋Œ€๊ฐ€ ๋ช‡ ๋ฒˆ ์ „๋ด‡๋Œ€์ธ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

์ถœ๋ ฅ

์ „์„ ์ด ๊ผฌ์ด์ง€ ์•Š์œผ๋ ค๋ฉด ์ตœ์†Œ ๋ช‡ ๊ฐœ์˜ ์ „์„ ์„ ์ž˜๋ผ๋‚ด์•ผ ํ•˜๋Š” ์ง€๋ฅผ ์ฒซ์งธ ์ค„์— ์ถœ๋ ฅํ•œ๋‹ค.

 

ํ’€์ด

๊ทธ๋ฆผ์œผ๋กœ ์ƒ๊ฐํ•˜๋ฉด ์กฐ๊ธˆ ์–ด๋ ต์ง€๋งŒ ํ’€์ด๋ฒ•๋งŒ ์ƒ๊ฐํ•ด๋‚ด๋ฉด ์˜์™ธ๋กœ ๊ฐ„๋‹จํ•˜๋‹ค

 

์ด ๋ฌธ์ œ์˜ ๋ชฉํ‘œ๋ฅผ ๋ณด์ž

: ์ตœ์†Œํ•œ์˜ ์ „์„ ์„ ์ž˜๋ผ๋‚ด์„œ "๊ผฌ์ด์ง€ ์•Š์€ ์ƒํƒœ์˜ ์ „์„ ๋“ค"๋งŒ ๋‚จ๊ฒจ๋‘ฌ์•ผํ•œ๋‹ค.

 

์ „์„ ์ด ๊ผฌ์ด์ง€ ์•Š์œผ๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?

๋ฐ˜๋Œ€๋กœ ์ƒ๊ฐํ•ด๋ณด์ž, ์ „์„ ์ด ๊ผฌ์ด๋Š” ๊ฒฝ์šฐ๋Š” ์–ด๋–ค ๊ฒฝ์šฐ์ผ๊นŒ?

ํ•œ ์ „๋ด‡๋Œ€๊ฐ€ '์ž์‹ ์˜ ์•ž์— ์žˆ๋Š” ์ „๋ด‡๋Œ€๊ฐ€ ์—ฐ๊ฒฐ๋œ ์ „๋ด‡๋Œ€'์˜ ์•ž์ชฝ ์ „๋ด‡๋Œ€์™€ ์—ฐ๊ฒฐ๋˜๋ฉด ๊ทธ ์ˆœ๊ฐ„ ์ „์„ ์€ ๊ผฌ์ด๊ฒŒ ๋œ๋‹ค.

์™ผ์ชฝ ๊ธธ์— ์žˆ๋Š” ์ „๋ด‡๋Œ€๋ฅผ ๊ธฐ์ค€์œผ๋กœ, n๋ฒˆ์งธ ์ „๋ด‡๋Œ€๋Š” n-1๋ฒˆ์งธ ์ „๋ด‡๋Œ€๊ฐ€ ์—ฐ๊ฒฐ๋œ ์˜ค๋ฅธ์ชฝ ์ „๋ด‡๋Œ€๋ณด๋‹ค ๋’ค์ชฝ์— ์—ฐ๊ฒฐ๋˜์–ด์•ผํ•œ๋‹ค.

 

์„ค๋ช…์ด ๊ธธ์—ˆ์œผ๋‚˜ ๊ฒฐ๋ก ์€ ๊ฐ„๋‹จํ•˜๋‹ค.

๊ฐ€์žฅ ๊ธด ์ฆ๊ฐ€ํ•˜๋Š” ๋ถ€๋ถ„ ์ˆ˜์—ด์„ ๊ตฌํ•˜๋ฉด ๋œ๋‹ค. (= ์ตœ์žฅ ๋ถ€๋ถ„ ์ฆ๊ฐ€ ์ˆ˜์—ด, = Longest Increasing Subsequent)

๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ์ˆ˜์—ด์— ๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š” ์ „์„ ๋“ค์€ ๋‹ค ๋Š์–ด๋ฒ„๋ฆฌ์ž

 

์ตœ์žฅ ๋ถ€๋ถ„ ์ฆ๊ฐ€ ์ˆ˜์—ด์„ ๊ตฌํ•˜๋Š” ๊ณผ์ •์—์„œ๋Š” dp๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค

๋ณดํ†ต dp[i] : v[i]๋กœ ๋๋‚˜๋Š” ์ตœ์žฅ์ฆ๊ฐ€๋ถ€๋ถ„์ˆ˜์—ด <- ์ด๋ ‡๊ฒŒ ํ•˜๋Š”๋ฐ, ์ด ๊ฒฝ์šฐ ์ด์ค‘ for๋ฌธ์œผ๋กœ ์ธํ•ด ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ๋œฌ๋‹ค

์ด๋ถ„ํƒ์ƒ‰์„ ์ด์šฉํ•ด์„œ dp[i] : ๊ธธ์ด i์˜ ๊ฐ€์žฅ ๊ธด ์ฆ๊ฐ€ํ•˜๋Š” ๋ถ€๋ถ„ ์ˆ˜์—ด ์ค‘ ๊ฐ€๋Šฅํ•œ ๊ฐ€์žฅ ์ž‘์€ ๋งˆ์ง€๋ง‰ ๊ฐ’ ์œผ๋กœ ๊ตฌํ•ด๋ณด์ž

 

์ฝ”๋“œ

// ํ’€์ด : https://whkakrkr.tistory.com

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int getLowerBound(int target, vector<int>&v) {
    int left=0, right=v.size();
    while(left<right) {
        int mid = (right-left)/2 + left;
        if(v[mid] < target) {
            left = mid+1;
        } else {
            right = mid;
        }
    }
    return left;
}

int main() {
    // ์ž…๋ ฅ
    int n;
    cin >> n;
    vector<int>v(n);
    for(int i=0; i<n; i++) {
        cin >> v[i];
    }
    
    // ํ’€์ด
    vector<int>dp;
    dp.push_back(v[0]);
    for(int i=1; i<n; i++) {
        if(dp.back() < v[i]) {
            dp.push_back(v[i]);
        } else {
            int idx = getLowerBound(v[i], dp);
            dp[idx] = v[i];
        }
    }
    int lis = dp.size();
    
    // ์ถœ๋ ฅ
    cout << n - lis;
    
    return 0;
}

 

 

์‹œํ–‰์ฐฉ์˜ค 

dp๋ฅผ ์ด์šฉํ•˜์—ฌ ์ตœ์žฅ ์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด์„ ๊ตฌํ–ˆ์œผ๋‚˜ ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ๋–ด๋‹ค.

// ํ’€์ด : https://whkakrkr.tistory.com

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    // ์ž…๋ ฅ
    int n;
    cin >> n;
    vector<int>v(n);
    for(int i=0; i<n; i++) {
        cin >> v[i];
    }
    
    // ํ’€์ด
    vector<int>dp(n,0); // dp[i] : v[i]๋กœ ๋๋‚˜๋Š” ์ตœ์žฅ์ฆ๊ฐ€๋ถ€๋ถ„์ˆ˜์—ด
    dp[0] = 1;
    for(int i=1; i<n; i++) {
        int tmpMax = 0;
        for(int j=0; j<i; j++) {
            if(v[j]<v[i] && tmpMax<dp[j]) {
                tmpMax = dp[j];
            }
        }
        dp[i] = 1+tmpMax;
    }
    
    // longest increasing subsequent
    int lis = *max_element(dp.begin(), dp.end());
    
    // ์ถœ๋ ฅ
    cout << n - lis;
	
    
    return 0;
}

 

 

 

๋ฐ˜์‘ํ˜•