[2024 하계모각코] 3주차 결과

2024. 7. 15. 14:38·스터디/2024하계모각코

Dynamic Programming-3

 

동적계획법

1. 일반적으로 최적화문제(optimisation problem) 혹은 카운팅(counting) 문제에 적용된다.

2. 주어진 문제에 대한 순환식(recurrence equation)을 정의한다.

3. 순환식을 memoization 혹은 bottom-up 방식으로 푼다. 

 

최적화문제는 최솟값이나 최댓값 구하는 경우 또는 최단 경로 문제.

카운팅 문제는 어떤 특정한 해의 개수를 구하는 문제.

 

  • subproblem들을 풀어서 원래 문제를 푸는 방식. 그런 의미에서 분할정복법과 공통성이 있음.
  • 분할정복법에서는 분활된 문제들이 서로 disjoint하지만 동적계획법에서는 그렇지 않음.
  • 즉 서로 overlapping하는 subproblem들을 해결함으로써 원래 문제를 해결.

 


 

그렇다면 분할정복법과 동적계획법의 차이에 대해 더 자세히 알아보도록 하자.


 

분할정복법

quicksort의 경우, pivot을 기준으로 분활된 두 subproblem은 서로 disjoint하다.


동적계획법


Optimal Substructure

  • 어떤 문제의 최적해가 그것의 subproblem들의 최적해로부터 효율적으로 구해질 수 있을 때 그 문제는 optimal substructure를 가진다고 말한다.
  • 분할정복법, 탐욕적기법, 동적계획법은 모두 문제가 가진 이런 특성을 이용한다.

Optimal Substructure를 확인하기 위해서는 "최적해의 일부분이 그 부분에 대한 최적해인가?"라는 질문을 만족해야 한다.


그렇다면, 최장경로 문제도 앞의 순환식과 같은 방식으로 표현할 수 있을까?

 

최장경로 문제

노드를 중복 방문하지 않고 가는 가장 긴 경로

optimal substructure를 가지는가?

마지막 경우는 s에서 u까지 A에 속한 노드들과 동시 v모두 지나지 않고 가는 최장 경로 길이+ w(u,v)를 나타낸다.

즉, 최장경로 문제는 다른 형태의 optimal substucture를 가지는 것일 뿐 optimal substructure를 가지지 않는다고 말할 수는 없다.


 

Dynamic Programming-4 : Matrix-Chain Multiplication

pxq 행렬 A와 qxr 행렬 B를 곱할 때의 코드이다.

void product(int A[][], int B[][], int C[][]){
	for(int i=0;i<p;i++){
    	for(int j=0;j<r;j++){
        	C[i][j] = 0;
            for(int k=0; k<q;k++)
            	C[i][j] += A[i][k]*B[k][j];
         }
     }
}

 

pxq행렬과 qxr 행렬을 곱하면 q가 중복되므로 pxr행렬이 만들어진다.

곱셈연산의 횟수=pqr

 


Matrix-Chain 곱하기

 

행렬 A는 10x100, B는 100x5, C는 5x50

세 행렬의 곱 ABC는 두 가지 방법으로 계산가능(결합법칙이 성립)

(AB)C: 7,500번의 곱셉이 필요(10x100x5 + 10x5x50)

A(BC): 75,000번의 곱셉이 필요(100x5x50 + 10x100x50)

즉 곱하는 순서에 따라서 연산량이 다름

 

n개의 행렬의 곱 A1A2A3...An을 계산하는 최적의 순서는?

여기서 Ai는 p(k-1)xp(k)행렬이다.

 

Ai...Ak를 곱하면 pk-1pk가 만들어지고, Ak+1...Aj를 곱하면 pkpj가 만들어지므로 pi-1pkpj가 뒷부분에 붙는다.


계산 순서

int matrixChain(int n)
{
	for(int i=1;i<=n;i++)
    	m[i][i] = 0; //대각선을 0으로 채우기
    for(int r=1;r<=n-1;r++){ //채워야 할 대각선의 개수가 n-1개여서
    	for(int i=1; i<=n-r;i++){ //각 대각선의 값의 개수
        //r번째 대각선의 i번째 값
        	int j=i+r;
            m[i][j] = m[i+1][j] + p[i-1]*p[i]*p[j];
            for(int k=i+1;k<=j-1;k++){
            	if(m[i][j] > m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j])
                	m[i][j] = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
            }
         }
    }
    return m[1][n];
 }

시간복잡도 n의 3승


Dynamic Programming-5 : Longest Common Subsequence(LCS)

<bcdb>는 문자열 <abcbdab>의 subsequence이다.

<bca>는 문자열 <abcbdab>와 <bdcaba>의 common subsequence이다.

 

Longest Common Subsequence(LCS)는

입력으로 2개의 문자열이 들어올 때, 두 문자열의 common subsequence중 가장 긴 것을 찾는 문제이다.

<bcba>는 <abcbdab>와 <bdcaba>의 LCS이다.

 


순환식


int lcs(int m, int n) //m:length of X, n: length of Y
{
	for(int i=0;i<=m;i++)
    	c[i][0] = 0;
    for(int j=0;j<=n;j++)
    	c[0][j] = 0;
    for(int i=0;i<=m;i++){
    	for(int j=0;j<=n;j++){
        	if(x[i] == y[j])
            	c[i][j] = c[i-1][j-1] + 1;
            else
            	c[i][j] = Math.max(c[i-1][j], c[i][j-1]);
        }
    }
    return c[m][n];
}

시간 복잡도는 mn

'스터디 > 2024하계모각코' 카테고리의 다른 글

[2024하계모각코] 4주차 결과  (2) 2024.07.24
[2024 하계모각코] 4주차 목표  (0) 2024.07.24
[2024 하계모각코] 3주차 목표  (0) 2024.07.15
[2024 하계모각코] 2주차 결과  (1) 2024.07.08
[2024 하계모각코] 2주차 목표  (0) 2024.07.08
'스터디/2024하계모각코' 카테고리의 다른 글
  • [2024하계모각코] 4주차 결과
  • [2024 하계모각코] 4주차 목표
  • [2024 하계모각코] 3주차 목표
  • [2024 하계모각코] 2주차 결과
soyun5
soyun5
개발블로그
  • soyun5
    soyun5
    soyun5
  • 전체
    오늘
    어제
    • 분류 전체보기 (27)
      • 운영체제및실습 (0)
      • 프로그래밍언어개론 (0)
      • 데이터베이스 (0)
      • 클라우드 (0)
        • 2025 AWS Cloud 초급특강 (0)
      • 스터디 (23)
        • 2024하계모각코 (10)
        • 2024동계모각코 (13)
      • 웹개발 (0)
        • HTML, CSS, 자바스크립트 (0)
      • PS (0)
        • 백준 (0)
        • 프로그래머스 (0)
      • 앱개발 (0)
        • flutter (0)
      • C (0)
      • java (0)
        • 자료구조 (0)
        • 알고리즘 (0)
      • 깃허브 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Directory
    운영체제
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
soyun5
[2024 하계모각코] 3주차 결과
상단으로

티스토리툴바