πŸ•οΈ ICPC Sinchon/Dynamic Programming

[BOJ][C++] λ°±μ€€ 2313번: 보석 κ΅¬λ§€ν•˜κΈ°

선달 2024. 9. 23. 18:40
λ°˜μ‘ν˜•

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

 

문제

보석 κ°€κ²Œμ— μ—¬λŸ¬ κ°€μ§€μ˜ 보석이 μ§„μ—΄λ˜μ–΄ μžˆλ‹€. 각각의 보석은 μ •μˆ˜λ‘œ ν‘œν˜„λ˜λŠ” κ°€μΉ˜κ°€ μžˆλ‹€. λ•Œλ‘œλŠ” 저주받은 보석이 있기 λ•Œλ¬Έμ— κ°€μΉ˜κ°€ μŒμˆ˜κ°€ 될 μˆ˜λ„ μžˆλ‹€.

보석듀은 총 n개의 쀄에 λ‚˜μ—΄λ˜μ–΄ μžˆλ‹€. 이제 당신은 각각의 μ€„μ—μ„œ λͺ‡ 개의 보석을 κ΅¬λ§€ν•˜λ € ν•œλ‹€. μ΄λ•Œ, 각 μ€„μ—μ„œ 보석을 ꡬ맀할 λ•Œ 연속적인 보석듀을 ꡬ맀해야 ν•œλ‹€. 즉, μ–΄λŠ ν•œ μ€„μ—μ„œ 1, 2번 보석을 ꡬ맀할 μˆ˜λ„ 있고, 2, 3번 보석을 ꡬ맀할 μˆ˜λ„ μžˆμ§€λ§Œ, 1, 3번 보석을 ꡬ맀할 μˆ˜λŠ” μ—†λ‹€.

κ΅¬λ§€ν•˜λŠ” λ³΄μ„μ˜ κ°€μΉ˜μ˜ 총 합이 μ΅œλŒ€κ°€ λ˜λ„λ‘ 보석을 κ΅¬λ§€ν•˜λŠ” 방법을 μ°Ύμ•„λ‚΄λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 μ •μˆ˜ n(1 ≤ n ≤ 1,000)이 주어진닀. λ‹€μŒ 2×n개의 μ€„μ—λŠ” n개의 쀄에 λ‚˜μ—΄λœ 보석듀에 λŒ€ν•œ 정보가 주어진닀. λ¨Όμ € 각 쀄에 λ‚˜μ—΄λœ λ³΄μ„μ˜ 개수 L(1 ≤ L ≤ 1,000)이 주어지고, κ·Έ λ‹€μŒ 쀄에 L개의 μ •μˆ˜λ“€μ΄ 주어진닀. 각 μ •μˆ˜λŠ” 각 λ³΄μ„μ˜ κ°€μΉ˜λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. λ³΄μ„μ˜ κ°€μΉ˜λŠ” μ ˆλŒ“κ°’μ΄ 10,000보닀 μž‘κ±°λ‚˜ 같은 μ •μˆ˜μ΄λ‹€.

좜λ ₯

첫째 쀄에 λ³΄μ„μ˜ κ°€μΉ˜μ˜ 총 ν•©μ˜ μ΅œλŒ“κ°’μ„ 좜λ ₯ν•œλ‹€. λ‹€μŒ n개의 μ€„μ—λŠ”, μ€„μ—μ„œ λͺ‡ 번째 보석뢀터 λͺ‡ 번째 λ³΄μ„κΉŒμ§€λ₯Ό κ΅¬λ§€ν–ˆλŠ”μ§€λ₯Ό 좜λ ₯ν•œλ‹€.

λ§Œμ•½ μ΅œλŒ€κ°€ λ˜λŠ” κ²½μš°κ°€ μ—¬λŸΏμ΄λ©΄, κ΅¬λ§€ν•œ λ³΄μ„λ“€μ˜ 총 κ°œμˆ˜κ°€ μ΅œμ†Œκ°€ λ˜λŠ” 방법을 좜λ ₯ν•œλ‹€. 이와 같은 κ²½μš°λ„ μ—¬λŸΏμ΄λΌλ©΄, 좜λ ₯ν•œ n×2개의 μˆ˜λ“€μ„ ν•˜λ‚˜μ˜ μˆ˜μ—΄λ‘œ μƒκ°ν•˜μ—¬, μ‚¬μ „μ‹μœΌλ‘œ κ°€μž₯ μ•žμ— μ˜€λŠ” 경우λ₯Ό 좜λ ₯ν•œλ‹€.

 

풀이

μž…λ ₯ 쑰건을 보면 보석 κ°€μΉ˜μ˜ 총 합은

μ΅œλŒ€ n*L*(λ³΄μ„μ˜ κ°€μΉ˜ μ΅œλŒ“κ°’) = 1000*1000*10000 = 10,000,000,000 = 100μ–΅

23얡을 ν•œμ°Έ λ„˜κΈ°λ―€λ‘œ intκ°€ μ•„λ‹Œ long long으둜 ν•΄μ•Όν•œλ‹€

 

보석 각 μ€„λ§ˆλ‹€ dp 연산은 λ…λ¦½μ μœΌλ‘œ μ§„ν–‰ν•˜μ§€λ§Œ 

좜λ ₯ 첫 쀄에 μ΅œμ’…μœΌλ‘œ λ‚˜μ˜¨ 값을 λ³΄μ—¬μ€˜μ•Όν•˜κΈ° λ•Œλ¬Έμ—

μž…λ ₯을 μ „λΆ€ λ‹€ λ°›μ•„μ„œ μ €μž₯해놓고 μ‹œμž‘ν•΄μ•Όν•œλ‹€. (ν•„μžλŠ” vλΌλŠ” 벑터λ₯Ό μ‚¬μš©ν–ˆλ‹€)

 

dp[i] : λ³΄μ„κ°―μˆ˜, iλ²ˆμ§ΈκΉŒμ§€μ˜ μ΅œλŒ€ν•©

        // dp
        vector<ci>dp(length); // dp[i] : λ³΄μ„κ°―μˆ˜, iλ²ˆμ§ΈκΉŒμ§€μ˜ μ΅œλŒ€ν•©
        dp[0] = {1, v[i][0]};
        for(int j=1; j<length; j++) {
            ci before = dp[j-1];
            if(before.second<=0) {
                dp[j] = {1, v[i][j]};
            } else {
                dp[j] = {before.first+1, before.second+v[i][j]};
            }
        }

 

 

비ꡐ 쑰건이 κΉŒλ‹€λ‘­λ‹€.

1. λ³΄μ„μ˜ κ°€μΉ˜μ˜ 합이 μ΅œλŒ€κ°€ λ˜μ–΄μ•Όν•¨

2. κ°€μΉ˜μ˜ 합이 κ°™λ‹€λ©΄ -> λ³΄μ„μ˜ κ°―μˆ˜κ°€ 적어야함

3. κ°€μΉ˜λ„ κ°™κ³  κ°―μˆ˜λ„ κ°™λ‹€λ©΄ -> κ·Έλ‚˜λ§ˆ μ•žμͺ½μΈκ±°

// μ΅œλŒ€κ°€ λ˜λŠ” 첫번째 μœ„μΉ˜ κ΅¬ν•˜κΈ°
        int index = 0;
        int cnt = dp[index].first;
        int max_value = dp[index].second;
        for(int j=1; j<length; j++) {
            if(dp[j].second>=max_value) {
                if(dp[j].second==max_value && dp[j].first>=cnt) {
                    continue;
                }
                index = j;
                max_value = dp[j].second;
                cnt = dp[j].first;
            }
        }

 

κ²Œμ‹œνŒμ— μΉœμ ˆν•œ λ°˜λ‘€ λͺ¨μŒμ΄ μžˆλ‹€.

μ•„λž˜ 글에 λ‚˜μ™€μžˆλŠ” λ°˜λ‘€λ₯Ό λ‹€ μ„±κ³΅ν•˜λ©΄ 거의 성곡이닀

https://www.acmicpc.net/board/view/139927

 

 

μ½”λ“œ

// 풀이 : https://whkakrkr.tistory.com

#include <iostream>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> ci;

int main() {
	// μž…λ ₯
	int n;
	cin >> n;
	vector<vector<int>>v(n);
    for(int i=0; i<n; i++) {
        int tmp;
        cin >> tmp;
        v[i] = vector<int>(tmp);
        for(int j=0; j<tmp; j++) {
            cin >> v[i][j];
        }
    }
    
    // 풀이
    ll sum = 0;
    vector<ci> ans(n);
    for(int i=0; i<n; i++) {
        int length = v[i].size();
        
        // dp
        vector<ci>dp(length); // dp[i] : λ³΄μ„κ°―μˆ˜, iλ²ˆμ§ΈκΉŒμ§€μ˜ μ΅œλŒ€ν•©
        dp[0] = {1, v[i][0]};
        for(int j=1; j<length; j++) {
            ci before = dp[j-1];
            if(before.second<=0) {
                dp[j] = {1, v[i][j]};
            } else {
                dp[j] = {before.first+1, before.second+v[i][j]};
            }
        }
        
        // μ΅œλŒ€κ°€ λ˜λŠ” 첫번째 μœ„μΉ˜ κ΅¬ν•˜κΈ°
        int index = 0;
        int cnt = dp[index].first;
        int max_value = dp[index].second;
        for(int j=1; j<length; j++) {
            if(dp[j].second>=max_value) {
                if(dp[j].second==max_value && dp[j].first>=cnt) {
                    continue;
                }
                index = j;
                max_value = dp[j].second;
                cnt = dp[j].first;
            }
        }
        sum += max_value;
        ans[i] = {index+1-cnt+1, index+1};
    }
    
    // 좜λ ₯
    cout << sum << "\n";
    for(ci i : ans) {
        cout << i.first << " " << i.second << "\n";
    }
    
    return 0;
}

 

λ°˜μ‘ν˜•