动态规划---数字三角形模型(一)

简介: AcWing算法提高课内容,本文讲解 动态规划

文章目录

一、前言

二、AcWing 1015. 摘花生

1.题目

2.逻辑解释

3.AC代码

三、AcWing 1018. 最低通行费

1.题目

2.逻辑解释

3.AC代码

四、AcWing 1027. 方格取数

1.题目

2.逻辑解释

3.AC代码

五、AcWing 275. 传纸条

1.题目

2.逻辑解释

3.AC代码


一、前言

AcWing算法提高课内容,本文讲解 动态规划

本篇包括以下题目:

AcWing 1015. 摘花生

AcWing 1018. 最低通行费

AcWing 1027. 方格取数

AcWing 275. 传纸条

写博客有哪里不完善的地方或者有哪里表达错误希望大家提出来,博主会立即改正!望大家海涵


二、AcWing 1015. 摘花生

1.题目

本题链接:摘花生

本博客提供本题截图:

55.png

2.逻辑解释

拿到一个题目后,我们分为两步去考虑这个问题:

第一步: 把题目进行抽象:其实就是对于一个矩形,我们从它的左上角走到右下角,每一个点上都一个数值,走到一个点后就加上这个点的值,每次只能往右走或者往下走,问走到右下角的话,数值的累计最大值是多少。

第二步: 进行dp分析:比如我们现在在[i, j]这个点上,dp的关键就是分析这个点可以由哪个点转换而来:显然,对于这个点而言,根据题意可以由上面的一个点转换,亦可由左边的一个点转换过来,而我们的需求为最大值,故我们可以得到状态转移方程:f[i][j] = max(f[i - 1][j], f[i][j - 1]) + w[i][j];


3.AC代码

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
int w[N][N];
int f[N][N];
int main()
{
    int t;
    cin >> t;
    while (t -- ) 
    {
        int r, c;
        cin >> r >> c;
        for (int i = 1; i <= r; i ++ ) 
            for (int j = 1; j <= c; j ++ ) 
                cin >> w[i][j];
        for (int i = 1; i <= r; i ++ ) 
            for (int j = 1; j <= c; j ++ )
                f[i][j] = max(f[i - 1][j], f[i][j - 1]) + w[i][j];
        cout << f[r][c] << endl;
    }
    return 0;
}

三、AcWing 1018. 最低通行费

1.题目

本题链接:最低通行费

本博客提供本题截图:

777.png

2.逻辑解释

拿到一个题目后,我们分为两步去考虑这个问题:

第一步: 把题目进行抽象:其实就是对于一个矩形,我们从它的左上角走到右下角,每一个点上都一个数值,走到一个点后就加上这个点的值,每次只能往右走或者往下走,问走到右下角的话,数值的累计最小值是多少。

第二步: 进行dp分析:比如我们现在在[i, j]这个点上,dp的关键就是分析这个点可以由哪个点转换而来:显然,对于这个点而言,根据题意可以由上面的一个点转换,亦可由左边的一个点转换过来,这里或许你会考虑:那么边界情况是否需要我们特判呢?即当我们的i或者j等于1的时候,需要特判,这个题和上一个题的区别就有了,因为我们的数组是从下标1开始的,而因为我们数组为全局定义,i = 0和j = 0的点的值是默认为0的,而我们的需求为最小值,故我们需要去特判,故我们可以得到状态转移方程:

if (i != 1 && j != 1)
  f[i][j] = min(f[i - 1][j], f[i][j - 1]) + w[i][j];
else if (i == 1) f[i][j] = f[i][j - 1] + w[i][j];
else f[i][j] = f[i - 1][j] + w[i][j];

3.AC代码

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
int w[N][N];
int f[N][N];
int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i ++ ) 
        for (int j = 1; j <= n; j ++ ) 
            cin >> w[i][j];
    for (int i = 1; i <= n; i ++ ) 
        for (int j = 1; j <= n; j ++ ) 
            if (i != 1 && j != 1)
                f[i][j] = min(f[i - 1][j], f[i][j - 1]) + w[i][j];
            else if (i == 1) f[i][j] = f[i][j - 1] + w[i][j];
            else f[i][j] = f[i - 1][j] + w[i][j];
    cout << f[n][n] << endl;
    return 0;
}





目录
相关文章
|
6月前
|
算法
【动态规划专栏】专题一:斐波那契数列模型--------3.最小花费爬楼梯
【动态规划专栏】专题一:斐波那契数列模型--------3.最小花费爬楼梯
54 2
|
6月前
|
算法
【动态规划专栏】动态规划:卡特兰数---不同的二叉树
【动态规划专栏】动态规划:卡特兰数---不同的二叉树
65 0
|
27天前
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
6月前
|
存储 算法
数字三角形(很经典的动态规划问题)
数字三角形(很经典的动态规划问题)
|
6月前
代码随想录 Day35 动态规划04 01背包问题和完全背包问题 LeetCode T416 分割等和子集
代码随想录 Day35 动态规划04 01背包问题和完全背包问题 LeetCode T416 分割等和子集
42 0
|
算法
[蓝桥杯] 递归与递推习题训练
蓝桥杯比赛只有四十天左右啦,最近会按照模块更新一些有关蓝桥杯算法题。学习算法不仅仅是为了参见比赛,更是以后找工作的一个敲门砖。废话不多说,我们直接看题。
77 0
初学算法之动态规划---求最长公共子串
初学算法之动态规划---求最长公共子串
初学算法之递归---爬楼梯
初学算法之递归---爬楼梯
初学算法之---递归汉诺塔
初学算法之---递归汉诺塔