목록💻 현생/⛓ 알고리즘 (223)
궤도
문제 풀이 myunji.tistory.com/210?category=1154147 [백준] 2579번 : 계단 오르기 문제 풀이 동적계획법의 대표적인 문제 중 하나이다. 생각해보니 동적계획법은 대표하는 문제가 많은 것 같다...아무튼 이전까지의 문제들은 초기값을 받은 배열을 그대로 갱신하면서 값을 구 myunji.tistory.com 이 문제와 유사한 문제이다. 차이가 있다면 계단 오르기 문제에선 마지막 계단을 꼭 밟아야 했지만 여기선 마지막 포도주를 마실 필요가 없단 것이다. 위의 두 경우는 i번째 포도주를 마신 경우이고 마지막 경우는 i번째 포도주를 마시지 않은 경우이다. i번째 포도주를 마신 경우 1. i-1번째 포도주를 마시고 i-2번째 포도주는 마시지 않음. i-3번째 포도주에 대한 최댓값 2...
문제 풀이 n자리의 자연수가 있다고 하자. 우리는 왼쪽부터 오른쪽으로 값을 채워나가고 있고 i번째 자리의 값을 채우려 한다. i번째가 첫번째 자리, 그니까 가장 왼쪽에 위치한 자리만 아니라면 0~9까지 모든 수가 들어올 수 있다. i번째 자리에 0이 들어간다면 i-1번째 자리의 수는 1일 것이다. i번째 자리에 9가 들어간다면 i-1번째 자리의 수는 8일 것이다. i번째 자리에 k(1
문제 풀이 2와 3 모두로 나눌 수 있는 정수 i가 있을 때 이 정수 i를 1로 만드는 방법은 다음과 같다. 1. (정수 i/2를 1로 만드는 방법의 횟수) +1 2. (정수 i/3을 1로 만드는 방법의 횟수) +1 3. (정수 i-1을 1로 만드는 방법의 횟수) +1 이 중에서 가장 작은 값을 취하면 된다. 2또는 3으로 나누어 떨어지지 않는 수들은 조건을 적절히 빼주면 될 것이다. 소스코드 #include #include using namespace std; int min_arr[1000001] = { 0, }; int making_one(int num) { for (int i = 1; i N; cout
문제 풀이 동적계획법의 대표적인 문제 중 하나이다. 생각해보니 동적계획법은 대표하는 문제가 많은 것 같다...아무튼 이전까지의 문제들은 초기값을 받은 배열을 그대로 갱신하면서 값을 구했다. 하지만 이 문제는 그러면 안된다. i번째 계단을 밟는다고 생각하자. i번째 계단을 밟기 위해선 어떤 경로로 계단을 밟아야 했을까? i-3번째 계단을 밟고 i-1번째 계단을 밟은 뒤 i번째 계단을 밟거나(3번연속 계단을 밟을 수 없기 때문) i-2번째 계단을 밟고 i-1번째 계단을 건너뛰고 i번째 계단을 밟을 수 있을 것이다. 배열을 1개만 사용하면 안되는 이유가 이것이다. i번째의 계산을 할 때 i-1번째만 연속적으로 참조하던 지난 문제들과 달리 이건 불연속적으로? 지난 값들을 참고하기 때문에 초기 입력을 저장할 배열..
문제 풀이 이 문제도 동적계획법의 대표적인 문제 중 하나이다. 대표적인 풀이법에는 위에서 아래로 내려가는 방법과 아래에서 위로 올라가는 방법이 있는데, 후자가 훨씬 코드를 간단하게 짤 수 있다. i번째 줄을 계산한다고 하자. i번째 줄의 0번째(지금은 3)를 갱신하려면 i+1번째 줄의 0번째(7)와 더하거나 i+1번째 줄의 1번째(6)와 더하거나 이다. 둘 중 더 큰 값을 취하면 된다. 일반화하면 i번째 줄의 j번째 값을 갱신하려면 i+1번째 줄의 j번째 값과 i+1번째 줄의 j+1번째 값을 비교해 더 큰 값과 더하면 되는 것이다. 이를 n-1번째줄부터 1번째 줄까지 반복한 뒤 1번째 줄의 1번째 값을 리턴하면 된다. 소스코드 #include #include using namespace std; int ..
문제 풀이 이걸 이렇게 표현하는게 맞나? 싶지만 동적계획법 문제를 풀 때는 i번째가 ~라면 i-1번째는 뭐였을까? 라는 방법으로 접근하는 것이 좋다. 보통 문제를 풀 때 0번째가 이거라면 1번째는 이게 되고 2번째는...식으로 생각하기 마련인데 동적계획법은 반대 방향으로 가야한다. 이 문제도 마찬가지이다. 첫번째 두번째 집이 무슨 색인지는 궁금하지 않고, i번째 집을 빨간색으로 칠한다고 생각해보자. i번째 집이 빨간색이라면 i-1번째 집은 파란색(1번 경우)이나 초록색(2번 경우)일 것이다. 그렇다면 i번째 집을 빨간색으로 칠할 때의 최솟값은? 1번 경우와 2번 경우 중 더 작은 값을 택하면 될 것이다. 소스코드 #include #include using namespace std; int house[10..
문제 풀이 3차원 배열을 써야겠다! 라는 생각을 했다면 빨리 해결했을 것이고... 나처럼 거의 쓸 일 없는 3차원 배열을 대충 기억속에서 지우고 살았던 사람이라면 좀 걸렸을지도 모르겠다. 난 시간초과에 대한 강박이 있는데 그래서 이 문제에 재귀함수 호출을 전혀 쓰지 않았다. 조건을 보니 아무리 for문이 많이 돌아도 최대 20*20*20 = 8000번이길래 3중 for루프를 사용했다. 근데 다른 사람들의 풀이를 보니 거의 다 재귀를 사용하셨던데 뭐 이런 풀이도 있다는 걸 보는 정도로 봐주길... 소스코드 #include using namespace std; int w_func(int a, int b, int c) { //재귀를 약간 써도 시간초과가 생기지는 않는가 보다... int w[21][21][21..
문제 풀이 동적계획법의 입문(?) 문제이다. 정확히 말하자면 찐 입문은 재귀 함수로 구현된 피보나치 함수를 동적계획법으로 구현하는 것인데...거의 같은 구조이다. n>1 일 때 fib(n) = fib(n-1) + fib(n-2)이다. 그렇다면 fib(n)에서 0이 호출된 횟수는? 당연히 fib(n-1)에서 0을 호출한 횟수와 fib(n-2)에서 0을 호출한 횟수를 더한 값일 것이다. 1이 호출된 횟수 역시 마찬가지일 것이고... 소스코드 #include using namespace std; void fibo_cnt(int num) { int zero_cnt[41] = { 0, }; int one_cnt[41] = { 0, }; for (int i = 0; i