算法第三章上机实验报告
1.1 问题描述
一个商人穿过一个N×N的正方形的网格,去参加一个非常重要的商务活动。他要从网格的左上角进,右下角出。每穿越中间1个小方格,都要花费1个单位时间。商人必须在(2N-1)个单位时间穿越出去。而在经过中间的每个小方格时,都需要缴纳一定的费用。
这个商人期望在规定时间内用最少费用穿越出去。请问至少需要多少费用?
注意:不能对角穿越各个小方格(即,只能向上下左右四个方向移动且不能离开网格)
1.2 算法描述
该问题需要求最优解,而最优解依赖最优子解。运用递归求出最优子解后求出最优解。
#include <iostream>
#include <cstdio>
#define N 101
using namespace std;
int f[N][N], a[N][N], n;
int ans;
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
scanf("%d", &a[i][j]);
if(i==1&&j==1)f[i][j]=a[i][j];
if(i == 1&&j>1) f[i][j] = a[i][j] + f[i][j-1];
if(j == 1&&i>1) f[i][j] = a[i][j] + f[i-1][j];
}
for(int i = 2; i <= n; i++)
for(int j = 2; j <= n; j++) f[i][j] = min(f[i-1][j], f[i][j-1]) + a[i][j];
printf("%d\n", f[n][n]);
return 0;
}
1.3 问题求解:
1.1.1 根据最优子结构性质,列出递归方程式,
f[i][j] = min(f[i-1][j], f[i][j-1]) + a[i][j];
f[i-1][j]=min(f[i-2][j],f[i-1][j-1])+a[i-1][j]
f[i-1][j-1]=min(f[i-2][j-1],f[i-1][j-2])+a[i-1][j-1]
…………
f[i][1]=f[i-1][1]+a[i][1]
f[1][j]=f[1][j-1]+a[1][j]
1.1.2 给出填表法中表的维度、填表范围和填表顺序。
表的维度:二维
填表范围:i从1到n,j从1到n;
填表顺序:从左到右,从上到下
1.1.3 分析该算法的时间和空间复杂度
时间复杂度:O(n^2)
空间复杂度:运用二维表格存放原始数据和最优子结构,空间复杂度为O(n^2)
1.3 心得体会(对本次实践收获及疑惑进行总结)
基础不牢地动山摇,要好好学习算法好好巩固c++的基础。
2. 你对动态规划算法的理解和体会
要学会找到动态方程式,注意边界条件。