일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- SWIFT
- DFS
- 롯데정보통신
- 부주상골수술후기
- 스택
- IOS
- 부주상골증후군
- dp
- SQLD
- 리눅스
- 카카오인턴
- 카카오코테
- 코테
- c++
- sql
- 독일어
- 독학
- BFS
- 구현
- 부주상골수술
- 카카오인턴십
- 코딩테스트
- 프로그래머스
- 세브란스
- 백준
- 독일어독학
- 부주상골
- 분할정복
- ChatGPT
- istringstream
Archives
- Today
- Total
슈뢰딩거의 고등어
[백준] 14916 거스름돈 (DP) 본문
https://www.acmicpc.net/problem/14916
[풀이]
쭉 경우의 수를 적어보다보니 규칙이 보였다.
DP[i] = min(DP[i-5] + 1, DP[i-2] + 1)
DP[2] = 1, DP[5] = 1, DP[4] = 2
계산을 할 수 없는 경우들이 존재하는데 우리는 min 함수를 사용하기 때문에
계산을 할 수 없는 경우를 고려하려면 초기에 DP 함수를 987654321 로 초기화를 해주어서 계산이 가능한지 아닌지 판별하면 된다.
사실 1~100000 의 수에서 거슬름돈을 줄 수 없는 경우는 1과 3뿐이다.
하지만 위의 공식으로 돌리다보면 1, 3 을 큰 수로 설정 해두지 않으면 dp[1] , dp[3] 을 가져다쓰기 때문에 실패로 뜬다.
min(), max() 를 사용할 때는 기본적으로 각각 987654321, -1(or -987654321) 로 설정해두는 것을 잊지말자
#include <iostream>
#include <algorithm>
using namespace std;
int n;
int dp[100001];
void dynamic() {
dp[2] = 1; dp[4] = 2;
dp[5] = 1;
for(int i=6; i<=n; i++) {
dp[i] = min(dp[i-5], dp[i-2]) +1;
}
}
int main() {
scanf("%d", &n);
for(int i=0; i<=n; i++)
dp[i] = 987654321;
dynamic();
int ret = dp[n];
if(ret >= 987654321)
printf("-1\n");
else
printf("%d\n", ret);
}
'알고리즘' 카테고리의 다른 글
[백준] 17837 새로운 게임2 (0) | 2022.02.07 |
---|---|
[프로그래머스] SQL 고득점 키트 (0) | 2022.02.04 |
[백준] 1010 다리놓기 (조합의 수) n개에서 m개 뽑기 (0) | 2022.02.03 |
[백준] 9625 BABBA (0) | 2022.02.03 |
[프로그래머스] 다리를 지나는 트럭 (0) | 2022.02.03 |
Comments