PS

BOJ 1943 - 동전 분배

728x90

www.acmicpc.net/problem/1943

 

1943번: 동전 분배

세 개의 입력이 주어진다. 각 입력의 첫째 줄에 동전의 종류 N(1≤N≤100)이 주어진다. 각 입력의 둘째 줄부터 N+1째 줄까지 각각의 동전의 금액과 개수가 빈 칸을 사이에 두고 주어진다. 단, 원장선

www.acmicpc.net

 

문제에서 요구하는 것은 정확히 절반으로 나눠서 두개로 나눌 수 있는가 없는가 이며,

이를위한 DP 1차원 배열을 만드는데 i 번째 인덱스의 의미는 i 원을 만들어 낼 수 있는지 없는지 판별한값이 들어간다

 

합이 홀수라면 어떻게 나눠도 정확히 두개로 나눠서 가질 수 없으므로, 예외처리 해주고

합이 짝수인 경우에 한해서 DP 배열을 채운다.

 

이 문제에서 가장 핵심은, 탑다운 방식으로 탐색해야 한다는것이다.

반대의 방식으로 탐색하면 1원으로 모든 DP 배열을 채울 수 있다.

1원으로 2원, 3원, 4원 .... N 원 까지 전부 만들 수도 있어서, 문제의 조건과 맞지 않는 결과가 나오게된다.

 

 

- C++

#include <algorithm>
#include <cstring>
#include <iostream>
 
using namespace std;
 
int N;
pair<intint> coin[101]; // 동전의 가치, 동전의 갯수 
bool dp[50001]; // dp[i] => i 원을 만들어 낼 수 있는가 없는가 
 
int main() {
    cin.tie(0); ios_base::sync_with_stdio(0);
    
    for (int tc = 0; tc < 3++tc) {
        int sum = 0
        memset(dp, falsesizeof(dp)); // 매 케이스마다 초기화필요 
        dp[0= true// 0 원은 당연히 true 
        
        cin >> N;
        for (int i = 0; i < N; ++i) {
            cin >> coin[i].first >> coin[i].second; 
            sum += (coin[i].first * coin[i].second);
        }
        
        if (sum % 2 == 1) { // 합이 홀수면 절반으로 분배 불가능 
            cout << "0\n";
            continue;
        }
        
        sort(coin, coin + N);
        
        for (int i = 0; i < N; ++i) {
            for (int j = sum / 2; j >= coin[i].first; --j) {
                if (dp[j - coin[i].first]) {
                    for (int k = 0; k < coin[i].second; ++k) {
                        if (j + k * coin[i].first > sum / 2break;
                        dp[j + k * coin[i].first] = true;
                    }
                }
            }
        } 
        
        cout << dp[sum / 2<< "\n";
    }
    
    return 0;
}
cs

728x90

'PS' 카테고리의 다른 글

BOJ 19538 - 루머  (0) 2021.03.11
BOJ 7579 - 앱  (0) 2021.03.10
BOJ 1199 - 오일러 회로  (0) 2021.03.05
BOJ 2513 - 통학버스  (0) 2021.03.04
BOJ 1577 - 도로의 갯수  (0) 2021.03.03