λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

πŸ“ μ•Œκ³ λ¦¬μ¦˜/BOJ

[C++/BOJ] 2343 : 기타 레슨 (이진탐색) / μˆ˜μ •

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

문제

κ°•ν† λŠ” μžμ‹ μ˜ 기타 κ°•μ˜ λ™μ˜μƒμ„ λΈ”λ£¨λ ˆμ΄λ‘œ λ§Œλ“€μ–΄ νŒλ§€ν•˜λ €κ³  ν•œλ‹€. λΈ”λ£¨λ ˆμ΄μ—λŠ” 총 N개의 κ°•μ˜κ°€ λ“€μ–΄κ°€λŠ”λ°, λΈ”λ£¨λ ˆμ΄λ₯Ό λ…Ήν™”ν•  λ•Œ, κ°•μ˜μ˜ μˆœμ„œκ°€ λ°”λ€Œλ©΄ μ•ˆ λœλ‹€. μˆœμ„œκ°€ λ’€λ°”λ€ŒλŠ” κ²½μš°μ—λŠ” κ°•μ˜μ˜ 흐름이 끊겨, 학생듀이 λŒ€ν˜Όλž€μ— 빠질 수 있기 λ•Œλ¬Έμ΄λ‹€. 즉, i번 κ°•μ˜μ™€ j번 κ°•μ˜λ₯Ό 같은 λΈ”λ£¨λ ˆμ΄μ— λ…Ήν™”ν•˜λ €λ©΄ i와 j μ‚¬μ΄μ˜ λͺ¨λ“  κ°•μ˜λ„ 같은 λΈ”λ£¨λ ˆμ΄μ— λ…Ήν™”ν•΄μ•Ό ν•œλ‹€.

κ°•ν† λŠ” 이 λΈ”λ£¨λ ˆμ΄κ°€ μ–Όλ§ˆλ‚˜ νŒ”λ¦΄μ§€ 아직 μ•Œ 수 μ—†κΈ° λ•Œλ¬Έμ—, λΈ”λ£¨λ ˆμ΄μ˜ 개수λ₯Ό 가급적 쀄이렀고 ν•œλ‹€. 였랜 κ³ λ―Ό 끝에 κ°•ν† λŠ” M개의 λΈ”λ£¨λ ˆμ΄μ— λͺ¨λ“  기타 κ°•μ˜ λ™μ˜μƒμ„ λ…Ήν™”ν•˜κΈ°λ‘œ ν–ˆλ‹€. μ΄λ•Œ, λΈ”λ£¨λ ˆμ΄μ˜ 크기(λ…Ήν™” κ°€λŠ₯ν•œ 길이)λ₯Ό μ΅œμ†Œλ‘œ ν•˜λ €κ³  ν•œλ‹€. 단, M개의 λΈ”λ£¨λ ˆμ΄λŠ” λͺ¨λ‘ 같은 크기이어야 ν•œλ‹€.

κ°•ν† μ˜ 각 κ°•μ˜μ˜ 길이가 λΆ„ λ‹¨μœ„(μžμ—°μˆ˜)둜 주어진닀. μ΄λ•Œ, κ°€λŠ₯ν•œ λΈ”λ£¨λ ˆμ΄μ˜ 크기 쀑 μ΅œμ†Œλ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 κ°•μ˜μ˜ 수 N (1 ≤ N ≤ 100,000)κ³Ό M (1 ≤ M ≤ N)이 주어진닀. λ‹€μŒ μ€„μ—λŠ” κ°•ν† μ˜ 기타 κ°•μ˜μ˜ 길이가 κ°•μ˜ μˆœμ„œλŒ€λ‘œ λΆ„ λ‹¨μœ„λ‘œ(μžμ—°μˆ˜)둜 주어진닀. 각 κ°•μ˜μ˜ κΈΈμ΄λŠ” 10,000뢄을 λ„˜μ§€ μ•ŠλŠ”λ‹€.

좜λ ₯

첫째 쀄에 κ°€λŠ₯ν•œ λΈ”λ£¨λ ˆμ΄ 크기쀑 μ΅œμ†Œλ₯Ό 좜λ ₯ν•œλ‹€.


 

싀버1.

이진탐색은 늘 μ–΄λ ΅λ‹€

항상 뭘 μ΅œμ†Ÿκ°’, 쀑간값, μ΅œλŒ“κ°’μœΌλ‘œ μž‘μ•„μ•Όν•˜λŠ”μ§€ ν—·κ°ˆλ¦Ό

 

 

+ 3/29 μ΄ν•΄μ™„λ£Œ

어젯밀에 μžλ©΄μ„œ μƒκ°ν•΄λ΄€λŠ”λ° μ΄ν•΄ν•΄λ²„λ ΈμŒ

 

 

1 2 3 4 5 6 7 ... 27 28

 

μœ„ ν‘œλ₯Ό 봐바

λ§Œμ•½μ— 파일이 7개이고 파일 크기λ₯Ό 1λΆ€ν„° 7κΉŒμ§€ μž…λ ₯λ°›κ²Œ 되면,

λΈ”λ£¨λ ˆμ΄ ν•˜λ‚˜μ˜ μ΅œμ†Œ μš©λŸ‰μ€ 7이어야함. μ™œλƒλ©΄ ν•œ νŒŒμΌμ„ μͺΌκ°œμ„œ 담을 수 μ—†κ±°λ“ 

그리고 λΈ”λ£¨λ ˆμ΄ ν•˜λ‚˜μ˜ μ΅œλŒ€ μš©λŸ‰μ€ 28이겠지. μ™œλƒλ©΄ 7개 νŒŒμΌμ„ λ‹€ ν•©μ³μ„œ ν•œλ²ˆμ— 넣을 수 μžˆλŠ” μ΅œμ†Œκ°’μ΄λ‹ˆκΉŒ.

(1+2+3+4+5+6+7 = 28)

 

그리고 μš°λ¦¬κ°€ ꡬ해야 ν•  값도 λΈ”λ£¨λ ˆμ΄μ˜ μš©λŸ‰μž„. κ·Έλ‹ˆκΉŒ μ •λ¦¬ν•˜μžλ©΄

 

1. (이진탐색)μ΅œμ†Ÿκ°’, 쀑간값, μ΅œλŒ“κ°’μœΌλ‘œ λΈ”λ£¨λ ˆμ΄ μš©λŸ‰μ„ μ°ΎλŠ” κ±°λ‹€! λΌλŠ”κ±Έ μ•Œ 수 있고

2. μž…λ ₯받은 μˆœμ„œλ₯Ό μ§€μΌœμ•Όν•˜λ‹ˆκΉŒ sortλŠ” ν•˜λ©΄ μ•ˆλ˜κ΅¬

3. λΈ”λ£¨λ ˆμ΄ μš©λŸ‰(mid) * λΈ”λ£¨λ ˆμ΄ 개수(cnt) >= 총 νŒŒμΌλ“€μ˜ μš©λŸ‰ ν•©

4. μœ„ 식을 μ΄μš©ν•΄μ„œ cnt와 m(μž…λ ₯받은 λΈ”λ£¨λ ˆμ΄ 개수)을 λΉ„κ΅ν•˜λ©΄ 됨.

5. 그리고 m==cntμ—μ„œ λ°˜λ³΅λ¬Έμ„ λ©ˆμΆ”λ©΄ μ•ˆλ¨ : μ™œλƒλ©΄ μš°λ¦¬λŠ” λΈ”λ£¨λ ˆμ΄ ν•˜λ‚˜λ‹Ή "μ΅œμ†Œ" 길이λ₯Ό κ΅¬ν• κ±°λΌμ„œ! λκΉŒμ§€ νƒμƒ‰ν•΄μ•Όν•œλ‹€

 

 

 

λ‚˜μ˜ 풀이

#include <iostream>
#include <algorithm>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    int m;
    int blue[100001]={0};
    int minlen = 0;
    int maxlen = 0;
    int mid = 0;
    int result;
    cin >> n >> m;
    for (int i = 0; i < n; ++i){
        cin >> blue[i];
        maxlen += blue[i]; // μ΅œλŒ€ κΈΈμ΄λŠ” λͺ¨λ“  λ°°μ—΄μ˜ ν•©
        if(minlen < blue[i]) minlen = blue[i]; // μ΅œμ†Œ κΈΈμ΄λŠ” κ°’λ“€μ˜ μ΅œλŒ“κ°’
    }

    while(minlen <= maxlen){
        mid = (minlen + maxlen) / 2;
        int sum = 0;
        int cnt = 0;

        for (int i = 0; i < n; ++i){
            if(sum + blue[i] > mid){ // midλŠ” λΈ”λ£¨λ ˆμ΄ ν•˜λ‚˜μ˜ μš©λŸ‰
                sum = 0;
                cnt++;
            }
            sum += blue[i];
        }
        cnt++;
       
        if(cnt > m) {
            minlen = mid + 1;
        }
        else if(cnt <= m) {
            maxlen = mid-1;
            result = mid;
        }
        // cout << minlen <<" "<<mid<<" "<<maxlen<<"\n";
    }

    cout << result;
}

 

μœΌμ•„ 이뢄탐색 ν•œλ¬Έμ œλ§Œ 더 ν’€κ³  넀이버 μžμ†Œμ„œ μ“°λŸ¬ 가야지..