O maior valor de um presente
Há um presente colocado em cada casa de um tabuleiro de xadrez m*n, e cada presente tem um determinado valor (valor maior que 0). Você pode começar no canto superior esquerdo do tabuleiro para colocar os presentes na grade e mover uma grade para a direita ou para baixo de cada vez até chegar ao canto inferior direito do tabuleiro. Dado um tabuleiro de xadrez e o valor dos presentes nele, calcule o valor máximo de um presente que você pode ganhar?
Link: Oferta de Sword Points 47. O maior valor de um presente
Exemplo 1:
Entrada:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
Saída: 12
Explicação: Caminho 1→3→5→2→1 pode obter o maior valor um presente
1. Representação de status
Para este problema de “tipo de caminho”, nossa representação de status geralmente tem duas formas:
- i. A partir da posição [i, j],...;
- ii. Partindo da posição inicial e chegando na posição [i, j],...;
Aqui escolhemos a segunda forma de definir a representação do estado:
dp[i][j] significa: atingir a posição [i, j], o valor máximo neste momento.
2. Equação de transição de estado
Para dp[i][j], descobrimos que existem duas maneiras de alcançar a posição [i, j]:
- i. Da posição [i - 1, j] acima da posição [i, j], desça um passo. O valor do presente que você pode receber ao atingir a posição [i, j] é dp[i - 1 ][ j] + grade[i][j];
- ii. Da posição [i, j - 1] à esquerda da posição [i, j], dê um passo para a direita. Neste momento, o valor do presente que você pode receber ao atingir a posição [i , j] é dp[i][j - 1] + grade[i][j]
O que queremos é o valor máximo, então a equação de transição de estado é:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]
3. Inicialização
Para resolver algumas condições de contorno, podemos adicionar nós auxiliares.
Nesta questão, após "adicionar uma linha" e "adicionar uma coluna", todos os valores são 0.
4. Ordem de preenchimento do formulário
De acordo com o “Processo de Transferência de Estado”, a ordem de preenchimento do formulário é “preencher cada linha de cima para baixo” e “preencher cada linha da esquerda para a direita”.
5. Valor de retorno
O valor de dp[m][n] deve ser retornado.
Código:
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. Soma mínima do caminho de descida
Dada uma matriz de array inteiro quadrado nxn, encontre e retorne a soma mínima do caminho descendente através da matriz.
O caminho descendente pode começar em qualquer elemento da primeira linha e selecionar um elemento de cada linha. O elemento selecionado na próxima linha está no máximo a uma coluna de distância do elemento selecionado na linha atual (ou seja, o primeiro elemento diretamente abaixo ou diagonalmente à esquerda ou à direita). Especificamente, o próximo elemento na posição (row, col) deve ser (row + 1, col - 1), (row + 1, col) ou (row + 1, col + 1).
Link: Soma Mínima de Caminhos Descendentes
Entrada: matriz = [[2,1,3],[6,5,4],[7,8,9]]
Saída: 13
Explicação: Conforme mostrado na figura, existem dois caminhos descendentes com a menor soma
1. Representação de status
Para este problema de “tipo de caminho”, nossa representação de status geralmente tem duas formas:
- i. A partir da posição [i, j],...;
- ii. Partindo da posição inicial e chegando na posição [i, j],...;
Aqui ainda escolhemos a segunda forma de definir a representação de estado:
dp[i][j] significa: atingir a posição [i, j], a soma mínima de todos os caminhos descendentes.
2. Equação de transição de estado
Para dp[i][j], descobrimos que existem três maneiras de alcançar a posição [i, j]:
- i. Mova-se da posição diretamente acima de [i - 1, j] para a posição [i, j];
- ii. Mova da posição superior esquerda [i - 1, j - 1] para a posição [i, j];
- iii. Mova da posição superior direita [i - 1, j + 1] para a posição [i, j];
O que queremos é o “valor mínimo” nas três situações, e depois somar o valor da matriz na posição [i, j].
então
dp[i][j] = min(dp[i - 1][j], min(dp[i - 1][j - 1], dp[i - 1][j +1])) + matrix[i][j]
3. Inicialização
Para resolver algumas condições de contorno, podemos adicionar nós auxiliares.
Nesta questão, precisamos "adicionar uma linha" e "adicionar duas colunas". Todas as posições são inicializadas até o infinito e então a primeira linha é inicializada como 0.
4. Ordem de preenchimento do formulário
A ordem de preenchimento do formulário é de cima para baixo
5. Valor de retorno
Observe que o valor de dp[m][n] não é retornado aqui!
O título exige "desde que atinja a última linha", portanto deve retornar "o valor mínimo da última linha da tabela dp".
Código:
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;
}