반응형

문제 출처 :


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



알고리즘 분석 :


문제 해결에 필요한 사항

1. Dynamic Programming

2. 점화식 세우는 방법


이 문제는 결국 현재무게, 현재무게에서 다음 추를 더한 무게, 현재무게에서 다음 추를 뺀 무게(절댓값)을 이용하면 된다.


이때 dp로 변경시키기위해 dp를 다음과 같이 정의한다.


dp[i][weight] :: i번째에서 weight를 가지는가?


이제 이를 dp로 구현해보자.


void dfs(int i, int weight)

{

if (i > n)

return;

if (dp[i][weight] != -1)

return;


dp[i][weight] = 1;


dfs(i + 1, abs(weight - arr[i]));

dfs(i + 1, weight);

dfs(i + 1, weight + arr[i]);

}


i > n일때는 종료시점이니 return을 걸어주고, dp != -1일때는 dp값이 존재하는 메모이제이션 과정이다.


그 외에는 위에서 설명한 내용과 같다.



소스 코드 : 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <cstdio>
#include <cmath>
#include <memory.h>
using namespace std;
 
int arr[32];
int dp[31][31 * 500 + 2];
int chk[10];
 
int n;
void dfs(int i, int weight)
{
    if (i > n)
        return;
    if (dp[i][weight] != -1)
        return;
 
    dp[i][weight] = 1;
 
    dfs(i + 1, abs(weight - arr[i]));
    dfs(i + 1, weight);
    dfs(i + 1, weight + arr[i]);
}
 
int main()
{
    scanf("%d"&n);
 
    for (int i = 0; i < n; i++)
        scanf("%d"&arr[i]);
 
    memset(dp, -1sizeof(dp));
 
    dfs(00);
 
    int m;
    scanf("%d"&m);
 
    for (int i = 0; i < m; i++)
    {
        scanf("%d"&chk[i]);
        if (chk[i] > 15000)
            printf("N ");
        else if (dp[n][chk[i]] == 1)
            printf("Y ");
        else
            printf("N ");
    }
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


반응형

'Applied > 알고리즘 문제풀이' 카테고리의 다른 글

[2942번] 퍼거슨과 사과  (2) 2018.01.05
[1939번] 중량제한  (0) 2018.01.04
[1947번] 선물 전달  (0) 2017.12.18
[1236번] 성 지키기  (0) 2017.12.17
[10527번] Judging Troubles  (0) 2017.12.12