1 minute read

  • 분류: 다이나믹 프로그래밍

코드

#include <iostream>
using namespace std;

int n;
int table[31][40001] = {0,};
int weight[31];

bool dp(int num, int goal) {
    if(num==1) {
        if(weight[1]==goal || goal==0) return true;
        else {
            table[num][goal] = -1;
            return false;
        }
    }
    if(table[num][goal]==1) return true;
    else if(table[num][goal]==-1) return false;
    if(goal==weight[num]) return true;
    if(goal==0) return true;

    if(table[num-1][goal]==1) return true;
    if(table[num-1][goal]==0) {
        if(dp(num-1, goal)) return true;
        else table[num-1][goal] = -1;
    }
    if(table[num-1][goal+weight[num]]==1) return true;
    if(table[num-1][goal+weight[num]]==0) {
        if(dp(num-1, goal+weight[num])) return true;
        else table[num-1][goal+weight[num]] = -1;
    }
    if(table[num-1][abs(goal-weight[num])]==1) return true;
    if(table[num-1][abs(goal-weight[num])]==0){
        if(dp(num-1, abs(goal-weight[num]))) return true;
        else table[num-1][abs(goal-weight[num])] = -1;
    }
    table[num][goal] = -1;
    return false;
}

int main() {
    for(int i=0 ; i<31 ; i++) for(int j=0 ;j<40001 ; j++) table[i][j]=0;
    cin >> n;
    for(int i=1 ; i<=n ; i++) cin >> weight[i];

    int t;
    cin >> t;
    for(int i=0 ; i<t ; i++) {
        int goal;
        cin >> goal;

        if(dp(n, goal)) cout << "Y\n";
        else cout << "N\n";
    }
}
  • 코멘트

추 n개(인덱스 1~n)를 가지고 A를 재야 한다.

추 중에 가장 큰거를 M0 라고 하면 –> 추 (n-1)개를 가지고 A, A+M0, A-M0을 잴 수 있는가?

그 다음 큰거를 M1 라고 하면 –> 추 (n-2)개를 가지고 A, A+M1, A-M1, A+M0+M1, A+M0-M1, A-M0+M1, A-M0-M1 을 잴 수 있는가?


두번째로 작은거를 M(n-2) 라고 하면 –> 추 1개를 가지고 ~~~ 를 잴 수 있는가? 즉, 남은 1개의 추와 후보 무게가 같은가?

대략 이런 아이디어로 접근할 수 있다. 목표 goal에서 weight[k]를 더하거나, 빼거나, 냅두거나 하면서 k=1~n으로 탐색해 나간다.
가장 밑바닥에서는 goal과 weight[1] 이 같은지, 또는 goal==0인지 확인한다.

Tags: ,

Categories:

Updated: