动态规划-学习记录3
目标
之前写了较简单的dp二维数组的题,现在加大难度。
题目
题为:力扣-64.最小路径和
给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。(如下图示例)
说明:每次只能向下或者向右移动一步。
思路
1.又是二维网格,定义一个二维数组:
dp[某格所在的列数][某格所在的行数] = 走到该格的所有路径中最小的数字总和。
2.确定状态转移方程:
dp[m][n] = Min(dp[m-1][n] , dp[m][n-1]]) + grid[m][n]。
3.寻找边界:
dp[0][0] = grid[0][0];
dp[i][0] = dp[i-1][0] + grid[i][0];
dp[0][j] = dp[0][j-1] + grid[0][j];
代码
#include <stdio.h>
int main()
{
int grid[100][100];
int dp[100][100]; //m,n < 100
int m,n;
int i,j;
scanf("%d %d",&m,&n);
for(i = 0;i<m;i++)
{
for(j = 0;j<n;j++)
{
scanf("%d",&grid[i][j]);
}
}
//初始化dp
dp[0][0] = grid[0][0];
for(i = 1;i<m;i++)
{
dp[i][0] = dp[i-1][0] + grid[i][0];
}
for(j = 1;j<n;j++)
{
dp[0][j] = dp[0][j-1] + grid[0][j];
}
for(i = 1;i<m;i++)
{
for(j = 1;j<n;j++)
{
dp[i][j] = (dp[i-1][j] < dp[i][j-1] ? dp[i-1][j] : dp[i][j-1]) + grid[i][j];
}
}
printf("%d",dp[m-1][n-1]);
return 0;
}
总结
老三样:
1.明确数组含义。
2.建立状态转换方程,使规模逐级递减。
3.确定边界条件。