티스토리 뷰

알고리즘/메모

알고리즘 메모장

산타 브라운 2018. 1. 13. 15:33

[Brute Force]

가능한 모든 경우의 수를 만들어보고 탐색하는 방법.

가능한 모든 경우의 수를 알아야함 => 경우의 수가 너무 많으면 불가


[BFS]

1.상태의 개수: 1초안에 나올 정도로 작아야함.

2.'최소' 구하는 문제

3.상태와 상태를 연결하는 간선의 가중치가 모두 1.


0.graph & check 배열 정의

1.시작을 '큐' 넣는다.

while(!q.empty()){

q.pop()

q.push(다음 정점)

if(!check[정점] && map[][] == 1){

check[정점] = true;

...

}

}


- check[]로 각 노드 1/0(true/false)

- 또는, dist[]로 각 노드까지의 거리 메모


[DFS]

1)

'재귀함수' 사용 => Stack을 사용하는 경우는 극히 일부.

0.graph & check 배열 정의

void dfs(int start, int size){

    cout << start << " ";

    s.push(start); // 시작점을 스택에 넣음

    check[start] = true; // 지나갔으니 체크!

    for(int i=1; i<=size; i++){

        if(a[start][i] && !check[i]){ // 시작점이랑 연결된 곳을 정한다

            check[i] = true; // 지나간다!

            dfs(i,size); // 그곳에서 이걸 반복해나간다

            s.pop(); // 갔다왔으면 스택에서 뺀다!

        }

    }


}


2) 가장 일반적

int dx[] = {0,0,-1,1};

int dy[] = {-1,1,0,0};


void dfs(int x, int y){

    map[x][y] = 1;

    visit[x][y] = 1;

    //

    for(int i=0; i<4; i++){

        for(int j=0; j<4; j++){

            int nx = x + dx[i];

            int ny = y + dy[i];

            if(nx<0 || nx>=n || ny<0 || ny>=n) continue;

            if(!visit[nx][ny] && map[nx][ny] == 1) {

                //

                dfs(nx,ny,color);

                //

            }

        }

    }

}

=> 이미 확인한 부분은 visit배열로 true/false(1/0).

=> 또는, map 값을 아예 0으로 만든다.



[DP: 다이나믹 프로그래밍]

-풀이 전략

문제에서 구하려고 하는 답을 문장으로 나타낸다.

문장에 나와있는 변수의 개수만큼 메모하는 배열을 만든다.


다이나믹 프로그래밍에서 문제는 번만 풀어야한다.

따라서, 정답을 구했으면, 정답을 어딘가에 메모한다.

메모하는 것을 코드의 구현에서는 배열에 저장하는 것으로 있다.(Memorization)

ex) memo[n] = n번째 피보나치

int memo[100];

int fibonacci(int n){

if(n<=1) return n;

else

if(memo[n] > 0) return memo[n];


memo[n] = fibonacci(n-1) + fibonacci(n-2);

return memo[n];

}


*문제 풀이 전략

  • 문제에서 구하려고 하는 답을 문장으로 나타낸다.
  • ) 피보나치 수를 구하는 문제
  • N번째 피보나치
  • 이제 문장에 나와있는 변수의 개수만큼 메모하는 배열을 만든다.
  • Top-down 경우에는 재귀 호출의 인자의 개수
  • 문제를 작은 문제로 나누고, 수식을 이용해서 문제를 표현해야 한다.


-큰 문제를 작은 문제로 나눠서 푸는 알고리즘.

1.Overlapping Subproblem

: 문제와 작은 문제를 같은 방법으로 있다.

:문제를 작은 문제로 쪼갤 있다.


2.Optimal Substructure

:문제의 정답을 작은 부분에서 찾을 있을


-푸는 방법은 크게 두가지

<Top-down>

1.문제를 작은 문제로 나눈다.

2.작은 문제를 푼다.

3.작은 문제를 풀었으니, 이제 문제를 푼다.

=>재귀호출 쉽게 있다.


<Bottom-up>

1.문제를 크기가 작은 문제부터 차례대로 푼다.

2.문제의 크기를 조금씩 크게 만들면서 문제를 점점 푼다.

3.작은 문제를 풀면서 왔기 때문에, 문제는 항상 있다.

4.그러다보면, 언젠가 풀어야 하는 문제를 있다.

ex)

int d[100];

int fibonacci(int n){

d[0] = 0;

d[1] = 1;

for(int i=2; i<=n; i++){

d[i] = d[i-1] + d[i-2]; // 식을 세우는 것이 제일 중요***** => 식을 못찾으면 못품.

}

return d[n]; // 정답 = d[n]

}



[재귀함수&백트래킹]

1.재귀함수 설계해야 한다.

2.백트래킹 경우...

-상태를 먼저 셋팅

-다음으로

-되돌아 왔을 , 셋팅 이전으로 되돌린다.(백트래킹)

ex) 재귀함수 'go' 있을때,

status = true;

go(x+1)

status = false;


[그리디 알고리즘]

최적의 답을 구하는 알고리즘으로 여러 경우 하나를 선택하는 매순간 마다 최적인 것을 골라 최종 답을 도출함.

ex) N원의 돈을 만드는 지페 최소 개수. K원을 받았을 거스름돈 최소 개수.


[스택]

stack<int> s;


[]

queue<int> q;



'알고리즘 > 메모' 카테고리의 다른 글

시간/공간 복잡도  (0) 2018.04.18
Visual Studio scanf 에러  (0) 2018.03.18
숫자 한 줄 입력받기  (0) 2018.02.14
STL 함수  (0) 2018.01.13
오답노트  (0) 2018.01.13
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/05   »
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 31
글 보관함