2017.11.02 ** 목요일 ** Solution - 1699(제곱수의 합)
백준 1699 제곱수의합

풀이방법: 동적계획법

엄청 시간이 걸렸던 문제다.

처음에 생각했던 것은 d[2-1] = d[1]+1.. 이런식으로 했었다.

그런데 여기서 4=2의 제곱이 되니 카운트가 바껴야 하는데 그 포인트를 못구했다.

그래서 중간에 월드시리즈 7차전을 잠깐보고 다시 문제를 풀었다.

오늘따라 다저스 타자들이 힘이 없어 보였다..나처럼 ㅜ

풀이방식

한번 생각해보자 ,

처음에 생각했던 방식 d[N - (N-1)] = d[N-1]+1 에 대해서 한번더 생각해보았다.

이렇게 하다보면 d[4]일때가 1차적으로 문제가 생기는데 ,

d[4-4] = d[0]+1을 만들어 줘야하기 때문이다.

자세히 식을 들여다보니 4 =2*2 가 된다. 그렇다면 1은 1x1이 된다는 것을 알 수 있다.

이제 반복문에 대해서 생각을 해보았다.

먼저 우리는 동적계획법을 할꺼고 bottom-up 방식을 사용하기 때문에 1부터 n까지 계산을

해줘야 된다.

for(int i = 1; i < n+1; i++) 로 시작하여

for(int j = 1l; j*j<i; j++)를 만든다. jxj < i 가 포인트인데 이유는

이렇게 하면 2의 제곱은 4부터 등장하게 되고, 처음 방식을 하면서 문제였었던 8은

d[8-4] = d[4] +1 = d[0] +1 +1 = 2가 될 수 있다.

따라서 조건에 의해 제곱수의 범위를 잘 나눌 수 있다. (손으로 해보는 것을 추천한다.)

점화식은 간단하다.

d[i] = Math.min(d[i],d[i-j*j]+1)

여기서 답을 놓칠뻔했다.

왜냐하면 d[i]를 초기화 해주지 않았다. d[i]의 초기화는 모두 d[i]=i로 해야된다.

이유는 모든 수는 1의 제곱으로 구성되어있기때문에, 1의 개수가 최대 개수가 된다.
코드 전체 보기

: 알고리즘은 항상 어렵다.

2017.10.31 ** 화요일 ** Solution - 1915(가장 큰 정사각형)

풀이방법: 동적계획법



문제 해석

기억난다.. 처음 풀었던 당시에 엄청 끙끙..거렸다는 것을..
알고보면 상당히 쉬운 문제이나 , 당시에 그 아이디어까지 가는데
머리가 좋지 않아서 2시간정도 걸렸던것 같다..

그 당시 풀이보다 시간복잡도가 반이나 줄어서 이렇게 포스팅하게 되었다.
(더 익숙해졌길래 의아했는데 , 알고보니 카카오 모의테스트 였구나..)



풀이방식

처음 이 문제를 접했을때는, 무식하게 완탐하려고했다.. 그렇게 시간이 흐르고 흘러

코드를 보니 엄청 더럽고, 내가 잘못하고 있다는 것을 알게되어 생각을 더하게 되었다.

문제를 잘보면 직관적으로 1로 이루어진 4각형이 보인다. 우리는 저 크기를 골라 내야한다.

처음에 시도했던 방법은 왼쪽위의 끝점(0,0)부터 계산해야하나 했다. 그런데 그렇게 하다보면

어떻게 사각형을 판별해야하는지 의문이 생긴다.

그래서 그 다음으로는 매핑되는 점을 선택해서 돌려보았다. 뭔가 사각형으로 마지막점까지 갈 수가 있어졌다.

그렇다면 어떻게 계산을 할지 고민해보았다. 예제에 있는 사각형을 보고 좀 전에 사각형 판별법과 같이 생각해보면

판별되는 숫자를 1로 감싸고 있다. ?!-> 아 변이 2다 ..그렇다면 1은 변이 1로 생각할 수 있겠다!




그렇다면 판별되는 숫자를 2로 바꿔주면 2가 될것같다.

다시 해석해보자면 판별되는 숫자를 기준으로 그 숫자와 나머지 3개가 같으면 +1로 증가시켜준다(정사각형이기때문에!)

하지만 잘생각해보면 0에서 -> 1도 만들어야하고 , 각각 한칸당 넓이가 1인 정사각형이다.

그래서 3개의 공간 ( 왼쪽위 , 바로위 , 왼쪽)을 비교해서 가장 작은 수를 +1시킨다.(그래야 주위에 0이 잇을때 1인 정사각형을 만듬)
->map[i][j] = Math.min(map[i - 1][j - 1], Math.min(map[i - 1][j], map[i][j - 1])) + 1;

그렇게 판별되는 정사각형의 넓이를 계산하여 최대 사각형의 넓이 변수 (maxCnt)와 비교하여 마지막에 출력한다.
->maxCnt = maxCnt < map[i][j] ? map[i][j] : maxCnt;

: 좀 마지막에 시간이 걸렸다.. 오류가 계속났다. 왜 그런지살펴보니 maxCnt*maxCnt가 답인데, 그냥 maxCnt만 출력했다..주의하자..





첫 알고리즘 포스팅입니다. 잘 부탁드립니다. 




2017.10.29 **,주말의 끝 일요일 ** Solution - 2665(미로 만들기)


풀이방법: 다익스트라


문제 해석


다익스트라의 일반적인 문제와 스타일이 비슷하다.
각 칸마다 지금까지 검은 벽을 지나온 개수들을 카운트 해준다. 최소화로 말이다.



풀이 방식



1. 초기화를 진행한다. dist의 초기 값은 0으로 셋팅한다.

2. 우선순위 큐를 설계한다. 값의 비교가 필요하니, 3개의 값을 가진 클래스를 설계한다.

3. 큐에 초기화가 적용된 출발 노드를 삽입한다.

4. 동작배열을 활용하여 상하좌우를 검색한다.

5. 조건을 나눈다. 1) 빈칸 2)검은색칸 이렇게 나눠서 계산한다.

6. 빈칸일경우 이전칸과 지금칸중에 가장 검은색칸을 적게 지나온 것으로 셋팅한다.

7. 검은칸일경우 지금의 칸을 지나는게( +1) 현재칸이 지나온 검은색칸보다 작다면 셋팅한다.

8. 현재의 칸에 대한 방문배열값을 true로 바꾼다.

9. while이 끝나고 값을 출력한다.




사실 이번 문제 같은 경우에는 딱히 해설이 필요없습니다. 단순히 다익스트라만 알면 풀수 있는 문제이고,
주의할점이 있다면 조건을 잘 나눠야하는것 밖에 없습니다.. 그래서 조금 해설이 정성이 부족한것도 있습니다.
궁금한점 있으시거나, 피드백을 해주실 분들은 댓글 달아주세요 !



(당부의 말씀 : 저는 고민을 먼저하고 문제를 풉니다. 다풀고나서 채점을 통해 맞으면 맞는거고, 틀리면 수정을 합니다. 하지만 저는 저만의 풀이가 끝나고 다른 사람들의 풀이와 비교를 통해 최적의 풀이방법을 찾으려 노력을 하고 있습니다. 만약 마지막 수정중에 다른분들것과 너무 흡사 하면 출저를 달아놓겠습니다.)

'알고리즘(추가예정) > 다익스트라' 카테고리의 다른 글

백준 1238 파티  (0) 2017.11.02

+ Recent posts