동적 프로그래밍 참고 사항

동적 프로그래밍 참고 사항



목차


  • Definition of dynammic programming
  • Common process to solve DP

  • Examples
  • 85. Maximal Rectangle




  • 动态规划 동적 프로그래밍



    Dynamic programming is both a mathematical optimization method and a computer programming method. The method was developed by Richard Bellman in the 1950s and has found applications in numerous fields, from aerospace engineering to economics.

    In both contexts it refers to simplifying a complicated problem by breaking it down into simpler sub-problems in a recursive manner. While some decision problems cannot be taken apart this way, decisions that span several points in time do often break apart recursively. Likewise, in computer science, if a problem can be solved optimally by breaking it into sub-problems and then recursively finding the optimal solutions to the sub-problems, then it is said to have optimal substructure.

    If sub-problems can be nested recursively inside larger problems, so that dynamic programming methods are applicable, then there is a relation between the value of the larger problem and the values of the sub-problems.[1] In the optimization literature this relationship is called the Bellman equation.




  • 동적 프로그래밍의 본질: 최적화

  • 원래 질문 <=> 몇 가지 유사한 독립적인 하위 문제
  • 상태 전이 방정식


  • 동적 프로그래밍 문제를 해결하기 위한 일반적인 프로세스


  • 결정하다 state

  • 즉, 원래 문제와 하위 문제의 양을 구분하기 위해 일반적으로 dp function의 인수 또는 dp array의 지수

    예: 원래 문제는 dp(n)이고 하위 문제는 dp(n-1)입니다.
  • 결정하다 base state case

  • 일반적으로 기본 상태=0, 즉 dp(0) 또는 dp[0]
  • 결정하다 strategy

  • 원래 문제를 하위 문제로 분해하는 다양한 방법에 관한 것입니다*
    예를 들어
    $$
    dp(엔)
    \= dp(n-1) + 2
    \=dp(n-2) + 1
    $$

  • 정의 dp function 또는 dp array (상태 전이 방정식)

  • 전략에 따라 방정식 작성

  • 위에서 아래로: dp 함수
    $$
    dp(n) =\min(dp(n-1)+2, dp(n-2)+1)
    $$
  • 일부 하위 문제가 반복적으로 계산될 수 있음 => 해시 테이블을 사용하여 계산된 하위 문제 저장
  • 시간 복잡도와 공간 복잡도가 높음


  • 아래에서 위로

     #state of original problem
     state_original_problem = 11
    
     #dp array
     dp = [some big value] * (state_original_problem+1)
    
     #base state
     dp[0] = dp[1] = 0
    
     #from bottom to top
     for i in range (2,len(dp)):
       dp[i] = min(dp[i-1]+2,dp[i-2]+1)
    
     return dp[-1]
    

  • 시간 복잡도 O(n), 공간 복잡도 O(n)
  • 최적화: dp[n]이 dp[n-1], dp[n-2]에만 관련된 경우 롤링 배열 아이디어를 사용하여 최적화할 수 있습니다.

  •    dp_i = 0 #dp[n-2]
       dp_j = 0 #dp[n-1]
    
       for i in range(2,n+1):
         dp_n =  min(dp_i+1,dp_j+2)
         dp_i = dp_j
         dp_j = dp_n
    
       return dp_j
    

    공간 복잡도: O(1)



    참조:

    知乎




    85. Maximal Rectangle

    0과 1로 채워진 rows x cols 이진 행렬이 주어지면 1만 포함하는 가장 큰 사각형을 찾고 해당 영역을 반환합니다.

    예 1:



    Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
    Output: 6
    Explanation: The maximal rectangle is shown in the above picture.
    


    动态规划思想:

    heights[i][j]代表[i,j]的高度
    heights[i][j] = matrix[i][j]=='1'? heights[i-1][j] + 1:0
    
    dp[i][j][k] 代表以[i,j]为右下角,高度为k可以组成的最大面积
    dp[i][j][k] = matrix[i][j]=='1'? dp[i][j-1][k] + k : 0
    




    代码:

    class Solution {
    public:
        int maximalRectangle(vector<vector<char>>& matrix) {
            int n = matrix.size();
            int m = 0;
            if (n > 0) { m = matrix[0].size(); }
            vector<vector<int>> heights(n + 1,vector<int>(m + 1,0));
            vector<vector<vector<int>>> dp(n + 1,vector<vector<int>>(m + 1, vector<int>(n + 1, 0)));
            int ans = 0;
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= m; j++) {
                    if (matrix[i-1][j-1] == '0') { continue; }
                    heights[i][j] = heights[i-1][j] + 1;
                    for (int k = 1; k <= heights[i][j]; k++) {
                        dp[i][j][k] = dp[i][j-1][k] + k;
                        ans = max(ans, dp[i][j][k]);
                    }
                }
            }
            return ans;
        }
    };
    

    좋은 웹페이지 즐겨찾기