티스토리 뷰
5557번: 1학년
상근이가 1학년 때, 덧셈, 뺄셈을 매우 좋아했다. 상근이는 숫자가 줄 지어있는 것을 보기만 하면, 마지막 두 숫자 사이에 '='을 넣고, 나머지 숫자 사이에는 '+' 또는 '-'를 넣어 등식을 만들며 놀
www.acmicpc.net


단순히 계산하면 n개의 숫자 사이에 n-2 개의 +, - 가 존재합니다. (마지막 부호는 = ) 그러므로
그러므로 DP를 이용해 봅시다.
상근이는 0~20까지의 숫자만 알고 있으므로 possible 배열을 이용하여 0~20에 다음 숫자를 계산했을 때 가능하면 dp 경우를 더해줍니다. 그 값을 dp배열에 복사하여 dp배열 내에서 0보다 큰 값이면 해당 숫자의 경우가 가능한 것이므로 이를 반복합니다.
그리고 마지막에서 두번째 수와 계산했을 때 맨 마지막 수가 나오는지 체크하면 됩니다.
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
int n;
vector<int>number;
ll dp[21];
ll possible[21];
ll res = 0;
void make_number()
{
cin >> n;
for (int i = 0; i < n; i++)
{
int a;
cin >> a;
number.push_back(a);
}
}
int main()
{
make_number();
memset(dp, 0, sizeof(dp));
dp[number[0]] = 1;
for (int i = 1; i < n - 2; i++) {
int num = number[i];
memset(possible, 0, sizeof(possible));
for (int j = 0; j < 21; j++) {
if (dp[j] > 0) {
if ((j + num >= 0) && (j + num <= 20)) {
possible[j + num] += dp[j];
}
if ((j - num >= 0) && (j - num <= 20)) {
possible[j - num] += dp[j];
}
}
}
memcpy(dp, possible, sizeof(dp));
}
int final_num = number[n - 2];
int result_num = number[n - 1];
for (int i = 0; i < 21; i++) {
if (dp[i] > 0) {
if (i + final_num == result_num)
res += dp[i];
if (i - final_num == result_num)
res += dp[i];
}
}
cout << res;
}
'알고리즘 > 백준' 카테고리의 다른 글
백준 / BOJ / 1389 케빈 베이컨의 6단계 법칙 C++ (0) | 2020.11.21 |
---|---|
백준 / BOJ / 1764 듣보잡 C++ (0) | 2020.11.19 |
백준 / BOJ / 16236 아기상어 C++ (0) | 2020.11.15 |
백준 / BOJ / 15937 두 박스 C++ (0) | 2020.11.12 |
백준 / BOJ / 2636 치즈 C++ (0) | 2020.11.10 |