UCI 프로그램을 연장하고 알고리즘 스터디를 열었다. 이전에도 Gist에 풀어온 코드를 올리고 있었지만 내 공부를 좀 더 기억하려면 시간을 들여 한 문제, 한 문제를 정리해나가는 것이 중요하다 생각했다.
이전에 Gist에는 단순히 코드만 올린 한편, 매 문제 포스팅마다 Code
,Concept & Idea
,Feeling
등을 적어보려 한다.
Problem
Concept & Idea
팰린드롬을 다이나믹 프로그래밍을 이용하여 푸는 문제였다. 또한 제한시간이 0.5초로 엄청 빡센 문제였다.
팰린드롬 체크를 단순히 떠오르는 방법으로 하게되면, 양쪽에서 체크하는 N^2만큼의 시간복잡도를 가진다.
그럼 이 문제를 다이나믹 프로그래밍을 이용하여 푸는 법은 무엇일까?
다이나믹 프로그래밍에서 가장 중요한 개념은 메모제이션이다. 또한 메모제이션을 어떻게 할 지 n에 대한 일반식으로 나타내는 것이 중요한 것 같다.
팰린드롬을 이전의 기록을 이용하여 체크할 때, ‘XXX라는 문자열이 팰린드롬이다’ && ‘_XXX_좌우에 붙는 문자들이 같다’ 라면 이 문자열 역시 팰린드롬이 된다.
이 Idea를 이용하여 다음 순서를 생각할 수 있다.
- 길이가 1인 문자열은 무조건 팰린드롬이다.
- 길이가 2인 문자열일 경우, 두 문자열이 동일하면 팰린드롬이다.
- XXX라는 문자열이 팰린드롬이고 해당 문자열 좌우에 새로운 문자들이 동일하면 팰린드롬이다.
참고로 DP[i][j]배열은 i부터 j까지 팰린드롬이라고 메모제이션 해놓은 배열이다.
또한 이 문제의 정답율이 낮은 이유는 입력과 출력시간이 cout과 cin을 이용하면 오래걸리기 때문이다.
필자는 scanf와 printf를 이용하여 풀었지만, Advice를 보면 cin.tie(NULL)과 sync_with_stdio(false)를 둘 다 적용해 주고, endl 대신 개행문자(\n)를 사용해서 해결할 수 있다.
근데 친구말을 들어보면, 그래도 scanf와 printf가 더 빠르다는데 잘 모르겠다.
Code
Fealing
사실 이 문제의 경우, 대각선을 기준으로 대칭을 이루기 때문에 굳이 N^2번 체크할 필요가 없다. (N^2)/2번 체크를 함으로써 시간을 단축시킬 수 있을 것 같다.
‘틀렸습니다’를 두려워 하지말고, 효율적인 코드를 짜는 연습을 해야한다.
Check out this code in Victoria’s Gist. Please Comment my code in this link.