λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Algorithm πŸ§‘πŸ»‍πŸ’»/λ°±μ€€(BOJ)

[λ°±μ€€,c++] 6236번 - 용돈 관리

by μ•ˆμ£Όν˜• 2022. 9. 8.

문제

 

6236번: 용돈 관리

ν˜„μš°λŠ” μš©λˆμ„ 효율적으둜 ν™œμš©ν•˜κΈ° μœ„ν•΄ κ³„νšμ„ 짜기둜 ν•˜μ˜€λ‹€. ν˜„μš°λŠ” μ•žμœΌλ‘œ N일 λ™μ•ˆ μžμ‹ μ΄ μ‚¬μš©ν•  κΈˆμ•‘μ„ κ³„μ‚°ν•˜μ˜€κ³ , λˆμ„ νŽ‘νŽ‘ 쓰지 μ•ŠκΈ° μœ„ν•΄ μ •ν™•νžˆ M번만 ν†΅μž₯μ—μ„œ λˆμ„ λΉΌμ„œ μ“°κΈ°λ‘œ

www.acmicpc.net

 

μ½”λ“œ

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

using namespace std;

int N, M, max_money;
vector<int> v;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    
    cin>>N>>M;
    
    for(int i=0; i<N; i++){
        int inp; cin>>inp;
        v.push_back(inp);
        max_money += inp;
    }
    int ans = 0;
    int start = 1, end = max_money; // μ΅œλŒ€ 인좜 κΈˆμ•‘μ€ λͺ¨λ“  λ‚ μ˜ μ΄μš©ν•  κΈˆμ•‘μ„ ν•©ν•œ 값이닀.
    
    while(start <= end){
        bool flag = false;
        int take_cnt = 1;
        int mid = (start + end) / 2;
        int money = mid;
        int temp_money = money;
        
        for(int i=0; i<v.size(); i++){
            if(v[i] > temp_money){
                take_cnt++;
                temp_money = money;
            }
            temp_money -= v[i];
            if(temp_money < 0){
                flag = true;
                break;
            }
        }
        if(flag || take_cnt > M) start = mid + 1;
        /*
            μ•„λž˜ 쑰건을 μΆ”κ°€ν•˜λ©΄ ν‹€λ¦Ό
            2 2
            100 200
            와 같은 λΆ€λΆ„μ—μ„œ 225λ₯Ό 좜λ ₯ν•˜λŠ”λ° 더 μž‘μ€ 값을 찾을 수 μžˆμŒμ—λ„ λΆˆκ΅¬ν•˜κ³  μ’…λ£Œν•˜κΈ° λ•Œλ¬Έ
         else if(take_cnt == M){
             cout<<money;
             break;
         }
         */
        else{
            ans = money;
            end = mid - 1;
        }
    }
    cout<<ans;
}

 

풀이

1원 ~ λͺ¨λ“  λ‚ μ˜ μ΄μš©ν•  κΈˆμ•‘을 ν•©ν•œ κ°’ μ‚¬μ΄μ˜ 값인 Kλ₯Ό 이뢄 탐색을 ν†΅ν•΄μ„œ μ°Ύμ•„, κ·Έ K의 κ°’λ§ŒνΌ μΈμΆœν–ˆμ„ λ•Œ 주어진 쑰건을 λ§Œμ‘±ν•˜λŠ”μ§€ νƒμƒ‰ν•˜λ©΄ λ©λ‹ˆλ‹€.

K의 값을 μ°ΎλŠ” 이뢄 탐색 O(logN) * μ΄μš©ν•  κΈˆμ•‘ 비ꡐ O(N) = O(NlogN) μ•ˆμ— 탐색이 κ°€λŠ₯ν•©λ‹ˆλ‹€. 

λ‹€λ§Œ μ½”λ“œμ—λ„ μ£Όμ„μœΌλ‘œ 써 놨닀 μ‹œν”Ό take_cnt == Mκ³Ό κ°™μ€ 쑰건을 톡해 break μ‹œν‚€λ©΄ 정닡이 μ˜¬λ°”λ₯΄μ§€ μ•Šμ€λ° κ·Έ μ΄μœ λŠ”

2 2
100 200
와 κ°™μ€ μž…λ ₯μΌλ•Œ 225μ—μ„œ K탐색을 μ’…λ£Œν•˜λŠ”λ°, 200μ΄λΌλŠ” 더 μž‘μ€ 값을 찾을 수 μžˆμŒμ—λ„ 끝내기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

λŒ“κΈ€