一、什么是动态规划
动态规划是一种将问题转化为子问题并且运用数组来求解的思想。
二、用动态规划解决问题
走方格问题
问从蓝点走到橙点的最短路径权值为多少(只能向右移或向下移)?
1 动态规划的步骤
1.1 确定状态
- 题目是说求起点到终点的最短路径权值,一般化后,状态就是从起点到某点的最短路径权值
- dp[i][j]表示从起点到某点的最短路径权值
1.2转移方程
- 要到终点,只有两条路可走,要么往右走到终点,要么往下走到终点,所以到终点的最短路径权值跟到这两个位置的最短路径权值有关
- 写出转移方程:dp[i]][j] = min(dp[i-1][j]+matrix[i-1][j],dp[i][j-1]+matrix[i][j-1])
1.3临界情况
- 对于第一行,只能往右走;对于第一列,只能往下走
1.4 确定计算顺序
- 从开始运算
2 代码部分
#include<stdio.h>
//输入矩阵的长和宽
void input_len_wid(int *len,int *wid)
{
printf("请输入矩阵的长和宽:\n");
scanf("%d %d",len,wid);
}
//输入矩阵信息
void input_matrix(int len,int wid,int *matrix)
{
printf("请输入矩阵信息:\n");
for(int j=0;j<wid;j++)
{
for(int i=0;i<len;i++)
{
scanf("%d",matrix+j*len+i);
}
}
}
//返回两者较小值
int min(int a,int b)
{
return a<=b?a:b;
}
//动态规划
int fun(int len,int wid,int *matrix)
{
int dp[wid][len] = {0};
dp[0][0] = *(matrix);
for(int i=1;i<len;i++)
{
dp[0][i] += dp[0][i-1];
}
for(int i=1;i<wid;i++)
{
dp[i][0] += dp[i-1][0];
}
for(int i=1;i<wid;i++)
for(int j=1;j<len;j++)
{
dp[i][j] = min(dp[i-1][j]+*(matrix+(i-1)*len+j),dp[i][j-1]+*(matrix+i*len+j-1));
}
return dp[wid-1][len-1];
}
int main()
{
int len,wid;
input_len_wid(&len,&wid);
int matrix[wid][len] = {0};
input_matrix(len,wid,&matrix[0][0]);
printf("最短路径权值为%d\n",fun(len,wid,&matrix[0][0]));
return 0;
}