[동적 프로그래밍 질문 4] 선물의 최대 가치&&하강 경로의 최소 합

선물의 가장 큰 가치

m*n 체스판의 각 칸에는 선물이 놓여 있고, 각 선물은 특정 가치(0보다 큰 가치)를 가지고 있습니다. 보드의 왼쪽 상단 모서리에서 시작하여 그리드의 선물을 가져오고 보드의 오른쪽 하단 모서리에 도달할 때까지 한 번에 하나의 그리드를 오른쪽이나 아래로 이동할 수 있습니다. 체스판과 그 위에 있는 선물의 가치를 고려하여 얻을 수 있는 선물의 최대 가치를 계산해 보세요.

링크: 소드 포인트 제공 47. 선물의 가장 큰 가치

예시 1:
입력:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
출력: 12
설명: 경로 1→3→5→2→1이 가장 큰 값을 얻을 수 있습니다. 자신의 선물

1. 상태 표현

이 "경로 유형" 문제의 경우 상태 표현은 일반적으로 두 가지 형식을 갖습니다.

  1. i. [i, j] 위치부터 시작,...;
  2. ii.시작 위치에서 시작하여 [i, j] 위치에 도달하는,...;

여기서는 상태 표현을 정의하는 두 번째 방법을 선택합니다.
dp[i][j]는 이 시점에서 최대값인 위치 [i, j]에 도달하는 것을 의미합니다.

2. 상태 전이 방정식

dp[i][j]의 경우 위치 [i, j]에 도달하는 두 가지 방법이 있음을 알 수 있습니다.

  1. i. [i, j] 위치에서 [i, j] 위의 위치에서 한 단계 아래로 내려갑니다. [i, j] 위치에 도달했을 때 얻을 수 있는 선물의 가치는 dp[i - 1 입니다. ][ j] + 그리드[i][j];
  2. ii.[i,j-1]위치에서 [i,j]위치에서 왼쪽으로 한걸음 오른쪽으로 한걸음 이동합니다.이때, [i,j]위치에 도달했을 때 얻을 수 있는 선물의 가치는 , j]는 dp[i][j - 1 ] + 그리드[i][j]입니다.

우리가 원하는 것은 최대값이므로 상태 전이 방정식은 다음과 같습니다.

dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i][j] 

3. 초기화

일부 경계조건을 해결하기 위해 보조 노드를 추가할 수 있는데,
이 질문에서 "행 추가"와 "열 추가" 후에는 모든 값이 0이 됩니다.

4. 양식 작성 순서
"국가 이전 프로세스"에 따르면 양식 작성 순서는 "각 줄을 위에서 아래로 작성", "각 줄을 왼쪽에서 오른쪽으로 작성"입니다.

5. 반환값
dp[m][n]의 값을 반환해야 합니다.

암호:

 int maxValue(vector<vector<int>>& grid) {
    
    
        int n=grid.size();
        int m=grid[0].size();
        vector<vector<int>> dp(n+1,vector<int>(m+1));

        for(int i=1;i<=n;i++)
        {
    
    
            for(int j=1;j<=m;j++)
            {
    
    
                dp[i][j]=max(dp[i][j-1],dp[i-1][j])+grid[i-1][j-1];
            }
        }
        return dp[n][m];
    }

여기에 이미지 설명을 삽입하세요.

931. 하강 경로의 최소 합

nxn 정사각형 정수 배열 행렬이 주어지면 행렬을 통과하는 하강 경로의 최소 합을 찾아서 반환하십시오.

내림차순 경로는 첫 번째 행의 모든 ​​요소에서 시작하여 각 행에서 하나의 요소를 선택할 수 있습니다. 다음 행에서 선택된 요소는 현재 행에서 선택된 요소(즉, 바로 아래 또는 대각선 왼쪽 또는 오른쪽의 첫 번째 요소)로부터 최대 한 열 떨어져 있습니다. 구체적으로 (row, col) 위치의 다음 요소는 (row + 1, col - 1), (row + 1, col) 또는 (row + 1, col + 1)이어야 합니다.

링크: 내림차순 경로의 최소 합계

여기에 이미지 설명을 삽입하세요.

입력: 행렬 = [[2,1,3],[6,5,4],[7,8,9]]
출력: 13
설명: 그림에 표시된 대로 합이 가장 작은 두 개의 하강 경로가 있습니다.

1. 상태 표현

이 "경로 유형" 문제의 경우 상태 표현은 일반적으로 두 가지 형식을 갖습니다.

  1. i. [i, j] 위치부터 시작,...;
  2. ii.시작 위치에서 시작하여 [i, j] 위치에 도달하는,...;

여기서는 상태 표현을 정의하는 두 번째 방법을 선택합니다.
dp[i][j]는 모든 하강 경로의 최소 합계인 위치 [i, j]에 도달하는 것을 의미합니다.

2. 상태 전이 방정식

dp[i][j]의 경우 위치 [i, j]에 도달하는 세 가지 방법이 있음을 알 수 있습니다.

  1. i. [i - 1, j] 바로 위 위치에서 [i, j] 위치로 이동합니다.
  2. ii.왼쪽 상단 위치 [i - 1, j - 1]에서 [i, j] 위치로 이동합니다.
  3. iii.오른쪽 상단 위치 [i - 1, j + 1]에서 [i, j] 위치로 이동합니다.

우리가 원하는 것은 세 가지 상황에서 "최소값"을 구한 다음, [i, j] 위치에 행렬의 값을 더하는 것입니다.
그 다음에

dp[i][j] = min(dp[i - 1][j], min(dp[i - 1][j - 1], dp[i - 1][j +1])) + matrix[i][j] 

3. 초기화

일부 경계 조건을 해결하기 위해 보조 노드를 추가할 수 있는데,
이 질문에서는 "행 1개 추가"와 "열 2개 추가"가 필요합니다. 모든 위치는 무한대로 초기화되고, 첫 번째 행은 0으로 초기화됩니다.

4. 양식 작성 순서
양식 작성 순서는 위에서 아래로 입니다.

5. 반환 값
dp[m][n] 값은 여기서 반환되지 않습니다.
제목에는 "마지막 행에 도달하는 한"이 필요하므로 "dp 테이블의 마지막 행의 최소값"을 반환해야 합니다.

암호:

    int minFallingPathSum(vector<vector<int>>& matrix) {
    
    
        int m=matrix.size();
        int n=matrix[0].size();
        vector<vector<int>> dp(m+1,vector<int> (n+2,INT_MAX));

        for(int i=0;i<n+2;i++) dp[0][i]=0;//初始化第一行的值
        int count=0;
        
        for(int i=1;i<=m;i++)
        {
    
    
            for(int j=1;j<=n;j++)
            {
    
    
                dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i-1][j+1]))+matrix[i-1][j-1];
            }

        }

        int ret=INT_MAX;//返回值
        for(int i=1;i<=n;i++) ret=min(ret,dp[n][i]);
        return ret;
    }

여기에 이미지 설명을 삽입하세요.

추천

출처blog.csdn.net/m0_64579278/article/details/132112128