Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

13-yuyu0830 #52

Merged
merged 3 commits into from
Jul 1, 2024
Merged

13-yuyu0830 #52

merged 3 commits into from
Jul 1, 2024

Conversation

yuyu0830
Copy link
Collaborator

πŸ”— 문제 링크

κ°€μž₯ κΈ΄ μ¦κ°€ν•˜λŠ” λΆ€λΆ„ μˆ˜μ—΄ 2(12015)

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

1μ‹œκ°„

✨ μˆ˜λ„ μ½”λ“œ

❓ 문제

μ΅œλŒ€ 길이 1,000,000의 μˆ˜μ—΄ Aκ°€ 주어진닀. λͺ¨λ“  μˆ«μžκ°€ μ˜€λ¦„μ°¨μˆœμœΌλ‘œ 배치된 μˆ˜μ—΄μ„ μ¦κ°€ν•˜λŠ” μˆ˜μ—΄ 이라고 ν•  λ•Œ, μˆ˜μ—΄ A의 κ°€μž₯ κΈ΄ μ¦κ°€ν•˜λŠ” λΆ€λΆ„ μˆ˜μ—΄μ˜ 길이λ₯Ό κ΅¬ν•˜μž!
(μˆ˜μ—΄μ˜ 각 숫자의 μ΅œλŒ€ 값은 1,000,000이닀.)

❗ 풀이

문제 μžμ²΄λŠ” κ°„λ‹¨ν•œλ° 풀이가 μ’€ μ‘°μ•…ν–ˆλ‹€. 처음 μƒκ°ν–ˆλ˜ 방법은 숫자의 μ΅œλŒ€κ°’μ΄ 1,000,000 이기 λ•Œλ¬Έμ— 각 μˆ«μžλ³„λ‘œ λ­”κ°€ μ €μž₯ν•˜λŠ”κ²Œ μ•„λ‹κΉŒ ν•˜λŠ” 생각을 ν–ˆμ—ˆλ‹€. ν•˜μ§€λ§Œ λ„μ €νžˆ λ˜λ ·ν•œ 해결책이 μƒκ°λ‚˜μ§„ μ•Šμ•˜λ‹€...

1️⃣ O(N^2)

O(N^2) 둜 ν‘ΈλŠ” 방법은 λͺ…λ°±ν–ˆλ‹€. arr[i] 의 κ°€μž₯ κΈ΄ μ¦κ°€ν•˜λŠ” λΆ€λΆ„ μˆ˜μ—΄μ˜ 길이 λ₯Ό m[i] 라고 ν•  λ•Œ, arr[j] (0 <= j < i) μ€‘μ—μ„œ arr[i]보닀 μž‘κ³  m[j]κ°€ κ°€μž₯ 큰 수λ₯Ό 골라 m[i] = m[j] + 1 을 λ°˜λ³΅ν•˜λ©΄ λœλ‹€. λ¬Όλ‘  μ΅œλŒ€ 길이가 1,000,000 이기 λ•Œλ¬Έμ— O(N ^2)λ‘œλŠ” ν’€ 수 μ—†μ—ˆλ‹€. 골머리λ₯Ό 싸맀닀가 κ²°κ΅­ LISλ₯Ό O(N log N) 으둜 ν•΄κ²°ν•˜λŠ” 법을 μ°Ύμ•˜λ‹€.

2️⃣ O(N log N)

κ²°κ΅­ μš°λ¦¬κ°€ μ°Ύμ•„μ•Όν•˜λŠ” 것은 "arr[j] 값이 arr[i]보닀 μž‘κ³  m[j]κ°€ κ°€μž₯ 큰 j κ°’" λ₯Ό μ°Ύμ•„μ•Ό ν•œλ‹€. μ—¬κΈ°μ„œ 우린 μ € 값을 μ°ΎκΈ° μœ„ν•΄ μ•žμ˜ λͺ¨λ“  값을 λ‹€ λ’€μ Έλ³Ό ν•„μš” 없이 "arr[i] 값보닀 μž‘μ€ κ°’μ˜ μ΅œλŒ€ m[j] κ°’" 을 μ €μž₯해두고 κ·Έ κ°’λ§Œ μ°Έμ‘°ν•˜λ©΄ O(N log N) 의 μ‹œκ°„λ³΅μž‘λ„λ‘œ 문제λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€!
즉 λ°°μ—΄ m[i] λŠ” "i 개의 숫자둜 λ§Œλ“€ 수 μžˆλŠ” λ°°μ—΄μ˜ λ§ˆμ§€λ§‰ μš”μ†Œκ°€ 될 수 μžˆλŠ” 값쀑 κ°€μž₯ μž‘μ€ κ°’" 이닀!

  1. μš°μ„  arr[i] 값을 순차적으둜 νƒμƒ‰ν•œλ‹€.
  2. λ§Œμ•½ arr[i] 값이 m[cnt - 1] 보닀 크닀면 (arr[i] 값이 μ•žμ„  λͺ¨λ“  값보닀 크닀면) m[cnt++] 값을 arr[i]둜 λ°”κΎΌλ‹€.
  3. λ§Œμ•½ arr[i] 값이 m[cnt - 1] 보닀 μž‘λ‹€λ©΄ arr[i] 보닀 μž‘μ€ m[j] 쀑 κ°€μž₯ 큰 값을 μ°ΎλŠ”λ‹€. 이 λ•Œ, νƒμƒ‰μ—λŠ” 이진 탐색을 μ‚¬μš©ν•œλ‹€.
  4. arr[i] 와 m[j] κ°€ 값이 κ°™λ‹€λ©΄ 별닀λ₯Έ 쑰치 없이 λ‹€μŒ 탐색을 이어간닀.
  5. arr[i] κ°€ m[j + 1] 보닀 μž‘λ‹€λ©΄ m[j + 1] 을 arr[i]둜 λ°”κΎΌλ‹€.
#include <iostream>

#define NUM 1000001
#define fastio ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);

using namespace std;

int n, cnt = 1;
int arr[NUM] = {0, };
int m[NUM] = {0, };

// Binary Search
int bs(int value) {
    int low = 0, mid, high = cnt - 1;

    while (low <= high) {
        mid = (low + high) / 2;

        if (m[mid] == value)
            return -1;

        if (value < m[mid]) high = mid - 1;
        else low = mid + 1;
    }

    return mid + (value < m[mid] ? -1 : 0);
}

int main() {
    fastio;

    cin >> n;
    for (int i = 0; i < n; i++)  
        cin >> arr[i];

    for (int i = 0; i < n; i++) {
        // if arr[i] is bigger than before
        if (arr[i] > m[cnt - 1]) {
            m[cnt++] = arr[i];
            continue;
        } 

        // if arr[i] is smaller than before 
        // find arr[i]'s position   
        int t = bs(arr[i]);
        // change m[t] to arr[i]
        m[t + 1] = arr[i] < m[t + 1] ? arr[i] : m[t + 1];
    }

    printf("%d\n", cnt - 1);
}

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

좜처 λ‚˜λ¬΄μœ„ν‚€ - 졜μž₯ 증가 λΆ€λΆ„ μˆ˜μ—΄https://namu.wiki/w/%EC%B5%9C%EC%9E%A5%20%EC%A6%9D%EA%B0%80%20%EB%B6%80%EB%B6%84%20%EC%88%98%EC%97%B4#s-3.1)

@yuyu0830 yuyu0830 changed the title 24/05/21 κ°€μž₯ κΈ΄ μ¦κ°€ν•˜λŠ” λΆ€λΆ„ μˆ˜μ—΄ 2 13-yuyu0830 May 21, 2024
Copy link
Collaborator

@InSange InSange left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

졜μž₯ 증가 λΆ€λΆ„ μˆ˜μ—΄ μ•Œκ³ λ¦¬μ¦˜ 되게 μ˜€λžœλ§Œμ— λ³΄λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€..
μ΄ˆλ°˜μ— ν—·κ°ˆλ¦¬λŠ” 뢀뢄이 μžˆμ—ˆλŠ”λ° λ‚˜λ¬΄μœ„ν‚€λ₯Ό 보고 단박에 이해 ν•΄λ²„λ ΈμŠ΅λ‹ˆλ‹€.

특히 첫 번째 μ•Œκ³ λ¦¬μ¦˜μ—μ„œ 두 번째 μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ λ„˜μ–΄κ°€κΈ° μœ„ν•΄ 이진 탐색을 λ„μž…ν•΄μ€€μ€„ μ•Œμ•˜λŠ”λ° 그럼 μ •λ ¬λ˜μ§€ μ•Šμ€ λ°°μ—΄λ‘œ λ‚˜νƒ€λ‚ ν…λ° μ™œ 이진 탐색을 μ‚¬μš©ν•œκ±°μ§€?μ—μ„œ μ‹œμž‘ν–ˆλŠ”λ° λ‚˜λ¬΄ μœ„ν‚€μ—μ„œ μ„€λͺ…ν•˜λ“― μ½”λ“œμ—μ„œλ„ 밑에 보면 μž‘μ€ 값이 λ“€μ–΄κ°ˆ 수 μžˆλŠ” λ²”μœ„ 자리λ₯Ό νƒμƒ‰ν•˜μ—¬ κ·Έ μžλ¦¬μ—μ„œλΆ€ν„° κ·Έ μžλ¦¬λ³΄λ‹€ 큰 값을 νƒμƒ‰ν•˜κ³  κ°±μ‹ ν•˜λŠ” 방법이 되게 μ‹ κΈ°ν–ˆμŠ΅λ‹ˆλ‹€.

@InSange InSange removed the request for review from dhlee777 June 28, 2024 02:00
Copy link
Collaborator

@seongwon030 seongwon030 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ €λŠ” κ°€μž₯ κΈ΄ μ¦κ°€ν•˜λŠ” λΆ€λΆ„μˆ˜μ—΄μ„ 처음 λ³΄λŠ”λ°μš”. μ˜¬λ €μ£Όμ‹  λ‚˜λ¬΄μœ„ν‚€ λ¬Έμ„œλ₯Ό λ³΄λ‹ˆκΉŒ 잘 μ΄ν•΄λ˜κ³  μƒˆλ‘œμš΄ μ•Œκ³ λ¦¬μ¦˜μ„ 배울 수 μžˆμ—ˆλ„€μš”! O(n2)의 μ‹œκ°„λ³΅μž‘λ„λ₯Ό κ°€μ§€λŠ” ν’€μ΄λŠ” λͺ¨λ“  λ°°μ—΄μš”μ†Œλ₯Ό μˆœνšŒν•˜κΈ° λ•Œλ¬Έμ— μˆœνšŒν•  λ•Œλ§ˆλ‹€ λΆ€λΆ„μˆ˜μ—΄μ˜ 길이λ₯Ό μ €μž₯ν•˜κ³ , 각 λΆ€λΆ„μˆ˜μ—΄λ§ˆλ‹€ 제일 λ§ˆμ§€λ§‰ μš”μ†Œ(제일 큰 수)와 λΉ„κ΅ν•΄μ„œ λΆ€λΆ„μˆ˜μ—΄μ˜ 길이λ₯Ό λ”ν•΄κ°€λŠ”κ²Œ λ³΅μž‘λ„κ°€ μ—„μ²­ μ€„μ–΄λ“œλŠ”κ²Œ μ‹ κΈ°ν–ˆμŠ΅λ‹ˆλ‹€.

@yuyu0830 yuyu0830 merged commit b938f9f into main Jul 1, 2024
@yuyu0830 yuyu0830 deleted the 13-yuyu0830 branch July 1, 2024 07:58
@yuyu0830 yuyu0830 mentioned this pull request Jul 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants