백준_문제풀이

[백준]: 5557번: 1학년 / DP(동적프로그래밍)

표기웅 2018. 9. 27. 21:12

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


해당문제는 N이 주어졌을 때, n-1까지의 +또는 - 의 값이 0<=Result<=20 사이로 들어와야 한다는 것이다.

간단하게 생각하면 재귀를 통해서 해결할 수 있다. 

그리고 생각없이 int형으로 return받다가 틀렸다고 떴는데, 2^100(2^N)이 꽤 크기에 int형으로 담지못한다. 따라서 long long타입으로 해야한다.


간단한 로직으로 설명하자면,

1. 기저조건 -> N== Index 가 맞는지? 맞다면 arr[N]==result가 같은지 (yes -> dp[index][result] ->1 / no -> dp[index][result] ->1

2. 미리계산한 값이라면 중복을 제거한다.

3. 재귀수행( result +arr[index] or result- arr[index] )



#include<iostream>

using namespace std;

#include<algorithm>

int n;

#include<cstring>

long long arr[105];

long long dp[200][200]; //iidx, sum 으로 

long long DP(int x,int result)

{

if (result < 0 || result>20)return 0;

if (x == n)

{

if (result == arr[x])

dp[x][result] = 1;

else

dp[x][result] = 0;

return dp[x][result];

}

if (dp[x][result] != -1)return dp[x][result];


long long ret = 0;

ret += DP(x + 1, result+ arr[x] );

ret += DP(x + 1, result-arr[x] );

dp[x][result] = ret;

return  dp[x][result];

int main()

{

cin >> n;

memset(dp, -1, sizeof(dp));

for (int i = 1 ; i <= n  ; i++)

cin >> arr[i];

cout << DP(2, arr[1]) << "\n";



return 0;

}