Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 완전탐색
- swea
- 그리디
- 동적계획법
- mst
- Kotlin
- 시뮬레이션
- java
- 백준
- 프로그래머스
- JUnit 5
- 수학
- 알고리즘
- CS
- 구현
- 에라토스테네스의 체
- 플로이드-와샬
- dfs
- 백트래킹
- 이분탐색
- 유니온 파인드
- Network
- 투 포인터
- Effective Java
- 문자열
- 위상정렬
- BFS
- 세그먼트 트리
- 스택
- 후니의 쉽게 쓴 시스코 네트워킹
Archives
반갑습니다!
[백준] 5557 1학년 본문
풀이
동적계획법으로 해결해야하는 문제이다. 문제를 읽고 단순하게 생각하면 DFS를 사용해서 해결할 수 있을 것 같지만, DFS를 사용하면 최대 O(2^100)
의 복잡도를 가지기 때문에 시간초과가 발생한다.
따라서 다른 방법을 고민해봐야하는데, 문제에 중간에 나오는 수 모두 0 이상 20 이하라는 말이 나온다. 이 점을 이용해서 dp[숫자 인덱스][중간의 나오는 수]
는 숫자 인덱스까지 수를 더했을 때 중간의 나오는 수가 될 수 있는 가지수를 구할 수 있다.
코드
C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
using namespace std; | |
int n; | |
long long ans; | |
int num[101]; | |
long long dp[101][21]; | |
int main() { | |
ios_base::sync_with_stdio(0); | |
cin.tie(0); | |
cin >> n; | |
for (int i = 1; i <= n; i++) | |
cin >> num[i]; | |
dp[1][num[1]]++; // 첫 번째 숫자만으로 num[1]을 만들 수 있는 가짓수는 1가지 | |
for (int i = 2; i <= n; i++) { | |
// 중간에 나오는 수가 모두 0 이상 20 이하이어야하므로 0부터 20까지만 반복한다 | |
for (int j = 0; j <= 20; j++) { | |
if (dp[i - 1][j]) { | |
// i 번째 숫자까지 사용해서 j + num[i]를 만들 수 있는 가짓수 계산 | |
if (j + num[i] <= 20) dp[i][j + num[i]] += dp[i - 1][j]; | |
// i 번째 숫자까지 사용해서 j - num[i]를 만들 수 있는 가짓수 계산 | |
if (j - num[i] >= 0) dp[i][j - num[i]] += dp[i - 1][j]; | |
} | |
} | |
} | |
cout << dp[n - 1][num[n]] << '\n'; | |
return 0; | |
} |
'알고리즘 문제 풀이' 카테고리의 다른 글
[백준] 12096 (0) | 2020.11.04 |
---|---|
[백준] 15663 N과 M (9) (0) | 2020.11.02 |
[백준] 1644 소수의 연속합 (0) | 2020.10.23 |
[백준] 2631줄 세우기 (0) | 2020.10.22 |
[프로그래머스] 최고의 집합 (0) | 2020.10.22 |