算法初步——超容易的动态规划(1):数字三角形模型
前言
时隔一年,在不久前学习完离散数学后便想着再次趁着超长寒假来继续学习算法~
这一系列将从之前报名的Acwing算法提高课选题,笔者会把这项课程分拆开来讲解清楚 !
希望能够帮助到各位快速上手算法~
一、问题1:摘花生


解题思路
本题实际上使用递归的思想。
和我们在数列里面学到的数列递推公式是异曲同工之妙
a n = k a n − 1 + b (这里 k , b 为常数) a_n=ka_{n-1}+b(这里k,b为常数) an=kan−1+b(这里k,b为常数)
如果有这个公式,还有a1,那么就必然可以求an
对于本题,递归就可以运用在第(n,m)格摘花生时的最大摘取量和在(n-1,m),(n,m-1)格摘花生时的最大摘取量的递推关系式求解。
我们设在(n,m)格摘花生时的最大摘取量为f[ n ][ m ],在 (n,m)格上有花生a[ n ][ m ]颗,我们就能列写出这样的公式(因为我们只能摘右边的或者下面的花生):
f[i][j]=max(f[i-1][j],f[i][j-1])+a[i][j];
因为我们本身知道在(1,1)格摘花生的最大摘取量就是它本身
代码如下:
#include <iostream>
using namespace std;
const int N = 105; //定义N超过100,使得空间足够
int a[N][N],f[N][N];
int num,row,col;
int main(){
cin>>num;
//键入花生所在处,这里采用num来判断是否按照指定要求键入完全
while(num--){
cin>>row>>col;
for(int i = 1;i<=row;i++){
for(int j = 1;j<=col;j++){
cin>>a[i][j];
}
}
// 遍历所有的格数,满足我们的递推关系:
//在第(n,m)格摘花生时的最大摘取量和在(n-1,m),(n,m-1)格摘花生时的最大摘取量
for(int i = 1;i<= row;i++){
for(int j = 1;j<=col;j++){
f[i][j]=max(f[i-1][j],f[i][j-1])+a[i][j];
}
}
cout<<f[row][col]<<endl; //输出花生摘取量
}
return 0;
}

成功AC!
二、问题2:最低通行费
解题思路
本题实际上和摘花生思路一致。摘花生要求最大的采摘量,这题就相当于求最小的采摘量。我们只用把max函数换成min函数即可,这里就不做详细赘述了,直接上代码!
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 105; //扩展
int n;
int a[N][N];
int f[N][N];
int main()
{
//键入每个地方的费用
cin >> n;
for (int i = 1; i <= n; ++ i)
for <

本文介绍了四个动态规划基础问题,包括数字三角形模型的摘花生问题、最低通行费问题、结合两个摘花生问题的方格取数以及类似方格取数的传纸条问题。通过递归思想和二维数组的更新,解决这些寻找最优路径或最大化/最小化目标的问题。代码示例展示了如何实现动态规划算法。


最低0.47元/天 解锁文章
5460

被折叠的 条评论
为什么被折叠?



