백준 1991 : 트리 순회


문제

이진 트리를 입력받아 전위 순회(preorder traversal), 중위 순회(inorder traversal), 후위 순회(postorder traversal)한 결과를 출력하는 프로그램을 작성하시오.

예를 들어 위와 같은 이진 트리가 입력되면,

  • 전위 순회한 결과 : ABDCEFG // (루트) (왼쪽 자식) (오른쪽 자식)
  • 중위 순회한 결과 : DBAECFG // (왼쪽 자식) (루트) (오른쪽 자식)
  • 후위 순회한 결과 : DBEGFCA // (왼쪽 자식) (오른쪽 자식) (루트)

가 된다.



입력

첫째 줄에는 이진 트리의 노드의 개수 N(1≤N≤26)이 주어진다. 둘째 줄부터 N개의 줄에 걸쳐 각 노드와 그의 왼쪽 자식 노드, 오른쪽 자식 노드가 주어진다. 노드의 이름은 A부터 차례대로 영문자 대문자로 매겨지며, 항상 A가 루트 노드가 된다. 자식 노드가 없는 경우에는 .으로 표현된다.




출력

첫째 줄에 전위 순회, 둘째 줄에 중위 순회, 셋째 줄에 후위 순회한 결과를 출력한다. 각 줄에 N개의 알파벳을 공백 없이 출력하면 된다.



예제 입력 1 


7
A B C
B D .
C E F
E . .
F . G
D . .
G . .

예제 출력 1

ABDCEFG
DBAECFG
DBEGFCA















풀이



'Algorithm > 재귀함수' 카테고리의 다른 글

CodeUp 1901 : (재귀 함수) 1부터 n까지 출력하기  (0) 2018.03.27

백준 11052 : 붕어빵 판매하기


문제

강남역에서 붕어빵 장사를 하고 있는 해빈이는 지금 붕어빵이 N개 남았다.

해빈이는 적절히 붕어빵 세트 메뉴를 구성해서 붕어빵을 팔아서 얻을 수 있는 수익을 최대로 만드려고 한다. 붕어빵 세트 메뉴는 붕어빵을 묶어서 파는 것을 의미하고, 세트 메뉴의 가격은 이미 정해져 있다.

붕어빵 i개로 이루어진 세트 메뉴의 가격은 Pi 원이다.

붕어빵이 4개 남아 있고, 1개 팔 때의 가격이 1, 2개는 5, 3개는 6, 4개는 7인 경우에 해빈이가 얻을 수 있는 최대 수익은 10원이다. 2개, 2개로 붕어빵을 팔면 되기 때문이다.

1개 팔 때의 가격이 5, 2개는 2, 3개는 8, 4개는 10 인 경우에는 20이 된다. 1개, 1개, 1개, 1개로 붕어빵을 팔면 되기 때문이다.

마지막으로, 1개 팔 때의 가격이 3, 2개는 5, 3개는 15, 4개는 16인 경우에는 정답은 18이다. 붕어빵을 3개, 1개로 팔면 되기 때문이다.

세트 메뉴의 가격이 주어졌을 때, 해빈이가 얻을 수 있는 최대 수익을 구하는 프로그램을 작성하시오.



입력

첫째 줄에 해빈이가 가지고 있는 붕어빵의 개수 N이 주어진다. (1 ≤ N ≤ 1,000)

둘째 줄에는 Pi가 P1부터 PN까지 순서대로 주어진다. (1 ≤ Pi ≤ 10,000)



출력

해빈이가 얻을 수 있는 최대 출력



예제 입력 1 

4
1 5 6 7

예제 출력 1 

10
















풀이


bottom-up 방식

cost[i] 에 기존 계산했던 값들을 저장해 놓고 cost[i] 와 비교 -> 메모제이션?

'Algorithm > DP' 카테고리의 다른 글

Baekjoon 11057 : (DP) 오르막 수  (0) 2018.03.28

CodeUp 1411 : 빠진 카드


문제 설명   
 

우리는 1부터 N까지의 숫자가 차례대로 적힌 N장의 카드 묶음을 가지고 있다.

그런 데 이 카드 묶음을 옮기는 중 실수로 땅에 떨어뜨려 그 중 한 장을 잃어버렸다.

여러 분은 땅에 떨어진 카드 묶음을 읽어서 빠진 하나의 카드 번호를 찾아 출력해야 한다.


입력

첫 줄에는 한 장을 잃어버리기 전 카드의 전체 장수 N이 주어져 있다. 단 . 3 <= N <= 50 이다.

이어지는 N-1개의 각 줄에는 한 장이 빠진 카드 묶음의 카드 숫자가 하나씩 순서 없이 나열되어 있다.

출력

여러분은 주 어진 카드 묶음에서 빠진 하나의 카드를 찾아서 그 번호를 출력해야 한다.


입력 예시   

10 3 4 1 10 2 6 7 5 9

출력 예시

8




풀이


1부터 N까지의 카드가 순서대로 있고 이를 찾았으면 TRUE(1), 아니면 찾지 못한 것으로 놓고

for 문으로 찾은 카드들을 입력받고 다시 for문으로 전체 카드들을 찾았는지 검사했다.


더 좋은 방법 => N을 입력할 때 1~N까지의 값들을 모두 더하고, 찾은 카드 입력받을 때 마다 빼주면 맨 마지막 남는 값이 정답이다.

Baekjoon 9372 : (BFS) 상근이의 여행


문제


상근이는 겨울방학을 맞아 N개국을 여행하면서 자아를 찾기로 마음먹었다. 

하지만 상근이는 새로운 비행기를 무서워하기 때문에, 최대한 적은 종류의 비행기를 타고 국가들을 이동하려고 한다.

이번 방학 동안의 비행 스케줄이 주어졌을 때, 상근이가 가장 적은 종류의 비행기를 타고 모든 도시들을 여행할 수 있도록 도와주자.

상근이가 한 국가에서 다른 국가로 이동할 때 다른 국가를 거쳐 가도(심지어 이미 방문한 국가라도) 된다.




입력

첫 번째 줄에는 테스트 케이스의 수 T(T ≤ 100)가 주어지고,

각 테스트 케이스마다 다음과 같은 정보가 주어진다.

  • 첫 번째 줄에는 국가의 수 N(2 ≤ N ≤ 1 000)과 비행기의 종류 M(1 ≤ M ≤ 10 000) 가 주어진다.
  • 이후 M개의 줄에 a와 b 쌍들이 입력된다. (a와 b를 왕복하는 비행기가 있다는 것을 의미한다)
  • 주어지는 비행 스케줄은 항상 연결 그래프(Connected Graph)를 이룬다.




출력

테스트 케이스마다 한 줄을 출력한다.

  • 상근이가 모든 도시를 여행하기 위해 타야 하는 비행기 종류의 최소 개수를 출력한다.






풀이


문제 자체가 잘 이해가 안되서 여러 번 읽어보았다.
국가의 수가 입력되는데, 5가 입력되면 1,2,3,4,5 라는 국가가 있는 것이다.
출력에서는 모든 도시를 여행해야하기 때문에, 입력을 할 때 모든 국가를 포함할 수 있도록 조심해야 겠다.


- 연결 그래프란?

모든 두 꼭짓점 사이에 경로가 존재하는 그래프이다.

모든 꼭짓점 사이에 경로가 존재할 때, 최소로 이용하는 비행기는 결국 최단 경로만 찾으면 된다.
최단 경로는 언제나 꼭짓점, 즉 국가의 갯수 - 1이다.


결과



테스트 케이스마다 한 줄 출력이라고 해서 위와 같이 코딩했는데 백준에서는 출력형식이 잘못되었다고 결과 나옴.
수정 필요!





Baekjoon 11057 : (DP) 오르막 수


문제


오르막 수는 수의 자리가 오름차순을 이루는 수를 말한다. 이 때, 인접한 수가 같아도 오름차순으로 친다.

예를 들어, 2234와 3678, 11119는 오르막 수이지만, 2232, 3676, 91111은 오르막 수가 아니다.

수의 길이 N이 주어졌을 때, 오르막 수의 개수를 구하는 프로그램을 작성하시오. 수는 0으로 시작할 수 있다.




입력

첫째 줄에 N (1 ≤ N ≤ 1,000)이 주어진다.




출력

첫째 줄에 길이가 N인 오르막 수의 개수를 10,007로 나눈 나머지를 출력한다.





DP(Dynamic Programming) 란??

간단히 말해, 작은 문제의 답을 조합하여 큰 문제의 답을 구하는 것이다.

다이나믹 프로그래밍 알고리즘을 적용하기 위해서는 아래와 같은 조건을 만족해야 한다.

  • Overlapping Subproblem
  • Optimal Substructure

Overlapping Subproblem 은 중복되는 부분 문제이다. 예를 들면 N번째 피보나치수를 구하는 문제를 구하는 문제는 N-1번째 N-2번째 피보나치 수를 구하는 문제가 되고 다른 수를 구할 때 같은 문제가 겹치는 경우가 생긴다.
큰 문제와 작은 문제를 같은 방법으로 풀 수 있어야한다. 그리고 문제를 작은 문제로 나누어서 풀 수 있어야한다.

Optimal Substructure 문제의 정답을 작은 문제의 정답을 구할 수 있다. 다이나믹 프로그래밍에서는 작은 문제들을 한 번만 풀어야한다.(시간을 줄이려면 당연히) 그리고 정답을 구했으면 이 답을 어딘가 메모해놓고 (Memoization) 이 답들을 이용해서 큰 문제를 푼다. 그리고 저장되는 공간을 cache라고 한다. 따라서 DP를 구현하기 위해서는 메모를 작성하는 부분과 메모를 읽는 부분이 필요하다. (위 풀이에서는 이 메모가 배열에서 이루어진 것인가?)

다이나믹 프로그래밍 문제를 푸는 방법에는 크게 두가지가 있다.

  • Top-down
  • Bottom-Up

Top down 방식으로 문제를 푸는 방법은 다음과 같다.

  1. 문제를 작은 문제로 나눈다.
  2. 작은 문제들을 푼다.
  3. 작은 문제들의 답으로 전체 문제를 푼다.

위의 피보나치 수열을 구하는 방법이 Top-down의 좋은 예이다. 주로 재귀함수를 이용해서 구현한다고 한다.

Bottom-Up 방식으로 문제를 푸는 방법은 다음과 같다.

  1. 가장 작은 문제부터 푼다.
  2. 문제의 크기를 점점 크게 만들어서 전체문제를 푼다.


(참고 : http://gnujoow.github.io/algo/2016/05/15/Algo0-dynamic-programing/)


'Algorithm > DP' 카테고리의 다른 글

백준 11052 : 붕어빵 판매하기  (0) 2018.04.07

CodeUp 1901 : (재귀 함수) 1부터 n까지 출력하기



문제


부터 정수 n 까지 출력하는 재귀함수를 설계하시오.

이 문제는 반복문 for, while 등을 이용하여 풀수 없습니다.




입력

정수 n이 입력된다




출력

1부터 n까지 한 줄에 하나씩 출력한다.





재귀함수란??


함수 안에서 함수 자기 자신을 호출하는 것을 재귀 호출이라고 한다.(recursive call)
일반적인 상황에선 쓰지 않지만 알고리즘을 구현할 때 매우 유용하다.
반복문으로 구현한 알고리즘 보다 코드가 더 직관적이이고 이해하기 쉽기 때문이다.

재귀함수 사용 시, 주의점은 종료 조건을 잘 만들어주어야 한다는 것이다.
종료를 못하면 언젠가 스택이 꽉차고, 스택 오버플로우가 일어나며 프로그램이 종료된다.

(참고 : https://dojang.io/mod/page/view.php?id=584)



'Algorithm > 재귀함수' 카테고리의 다른 글

백준 1991 : 트리 순회  (0) 2018.04.14

+ Recent posts