第四十二章 动态规划——数字三角形模型

news2024/11/16 11:36:10

第四十二章 动态规划——数字三角形模型

  • 一、数字三角形模型
    • 1、什么是数字三角形模型
  • 二、例题
    • 1、AcWing 1015. 摘花生
      • (1)问题
      • (2)思路
        • 状态表示
        • 状态转移
        • 循环设计
        • 初末状态
      • (3)代码
    • 2、AcWing 1018. 最低通行费
      • (1)问题
      • (2)思路
      • (3)代码
    • 3、AcWing 1027. 方格取数
      • (1)问题
      • (2)思路
      • (3)代码
    • 4、AcWing 275. 传纸条
      • (1)问题
      • (2)思路
      • (3)代码

一、数字三角形模型

1、什么是数字三角形模型

数字三角形模型常见于一个图中,而我们要做的决策是每一步往哪里走。那么这种题转移方程的书写思路是:**图中的哪几个点能够转移到当前的点。**然后我们根据题目的需要在选出一个符合题目要求的作为当前状态的答案。

二、例题

1、AcWing 1015. 摘花生

(1)问题

在这里插入图片描述

(2)思路

状态表示

f ( i , j ) f(i,j) f(i,j)表示从起点走到坐标为 ( i , j ) (i,j) (i,j)的点的时候,所携带的最大花生数目

状态转移

由于一个点只能往右走或者往下走,所以能够走到 ( i , j ) (i,j) (i,j)的点是左边的 ( i − 1 , j ) (i-1,j) (i1,j)和上面的 ( i , j − 1 ) (i,j-1) (i,j1),所以我们就能够利用这两个点写出转移方程:
f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j ] , f [ i ] [ j − 1 ] ) + w [ i ] [ j ] f[i][j]=max(f[i-1][j],f[i][j-1])+w[i][j] f[i][j]=max(f[i1][j],f[i][j1])+w[i][j]

循环设计

循环主要涉及到 j j j i i i,所以要么i嵌套j,要么j嵌套i,根据我们的转移方程,无论我们怎么枚举都可以都提前计算出子问题。因此,看自己喜好就行了。

但是还涉及到了i-1,j-1的问题,这种情况下,我们为了防止越界,可以用很好理解的方式,就是加上if语句特殊判断就行了。

但是由于这道题我们每个空最小值就是0,因此我们可以从1开始记录数据,这样0的位置存在的都是0,这是不影响答案的。

初末状态

这道题的初始状态就是没有捡花生的时候的数量,很明显是0,所以不用初始化了。
最后的状态就是走到了(n,n)这个点,即f[n][n]

(3)代码

#include<iostream>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
int n, m;
int w[N][N];
int f[N][N];
int main()
{
    int T;
    scanf("%d", &T);
    while (T -- )
    {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i ++ )
            for (int j = 1; j <= m; j ++ )
                scanf("%d", &w[i][j]);
        for (int i = 1; i <= n; i ++ )
            for (int j = 1; j <= m; j ++ )
                f[i][j] = max(f[i - 1][j], f[i][j - 1]) + w[i][j];

        printf("%d\n", f[n][m]);
    }
    return 0;
}

2、AcWing 1018. 最低通行费

(1)问题

在这里插入图片描述

(2)思路

这道题无非就是上一道题的思路从最大值到最小值,但是上一道题因为是最大值,所以边界初始化为0是可以的,但是这道题的话我们要求的是最小值,为了不让边界影响到答案,我们需要初始化为正无穷。

同时还要特殊判断一下左上角。

(3)代码

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

3、AcWing 1027. 方格取数

(1)问题

在这里插入图片描述

(2)思路

这道题的话,唯一的不同的是走两遍,这里我们的思路是我们让两条路同时走,可以走到相同的位置,但是同一个位置的数字只能取一次。

因为同时记录两个点,所以我们需要控制四个变量,即4维数组。

但是方程的书写思路不变,依旧是看哪几个点能走到当前位置,那么一条路的时候有两个,两条路的时候自然就有4个点。

大家可以自己思考怎么写,具体方程见代码。

(3)代码

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=15;
int w[N][N];
int f[N][N][N][N];
int main()
{
    int n;
    cin>>n;
    int a,b,c;
    while(scanf("%d%d%d",&a,&b,&c),a||b||c)
        w[a][b]=c;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            for(int k=1;k<=n;k++)
            {
                for(int m=1;m<=n;m++)
                {
                    int t=w[i][j];
                    if(i!=k||j!=m)t+=w[k][m];
                    int&x=f[i][j][k][m];
                    x=max(x,f[i-1][j][k-1][m]+t);
                    x=max(x,f[i-1][j][k][m-1]+t);
                    x=max(x,f[i][j-1][k-1][m]+t);
                    x=max(x,f[i][j-1][k][m-1]+t);
                }
            }
        }
    }
    cout<<f[n][n][n][n]<<endl;
    return 0;
}

4、AcWing 275. 传纸条

(1)问题

在这里插入图片描述

(2)思路

这道题和刚刚的题目思路是一样的,但是刚刚那道题是可以经过同一个点,但是不能取两遍数字。

但是这道题,每个点只能经过一遍,因此我们每次需要判断一下,我们当前状态所对的两个点是否相同。

(3)代码

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=60;
int g[N][N];
int f[N][N][N][N];
int n,m;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d",&g[i][j]);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            for(int p=1;p<=n;p++)
            {
                for(int q=1;q<=m;q++)
                {
                    if(i==p&&j==q)continue;
                    int t=g[i][j]+g[p][q];
                    int &x=f[i][j][p][q];
                    x=max(x,f[i-1][j][p-1][q]+t);
                    x=max(x,f[i][j-1][p][q-1]+t);
                    if(i-1!=p&&j!=q-1)
                        x=max(x,f[i-1][j][p][q-1]+t);
                    if(i!=p-1&&j-1!=q)
                        x=max(x,f[i][j-1][p-1][q]+t);
                }
            }
        }
    }
    cout<<max(f[n-1][m][n][m-1],f[n][m-1][n-1][m])<<endl;
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/150816.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第二章:感知机

文章目录2.1感知机模型2.2感知机策略2.3梯度下降法2.4感知机-原始算法形式2.5感知机-原始算法实例2.6感知机-对偶形式2.7感知机-对偶形式实例2.8感知机算法收敛性证明如下&#xff1a;2.1感知机模型 2.2感知机策略 损失函数非负&#xff0c;策略是选择使其最小的模型参数 2.3梯…

【Linux工具】-gcc/g++

gcc/g一&#xff0c;简介二&#xff0c;代码的翻译过程1&#xff0c;预处理2&#xff0c;编译3&#xff0c;汇编4&#xff0c;链接&#xff08;1&#xff09;静态库&#xff08;2&#xff09;动态库&#xff08;3&#xff09;动静态库比较三&#xff0c;常见选项一&#xff0c;…

模板(C++)

模板&#xff08;C&#xff09;泛型编程函数模板概念格式原理实例化匹配原则类模板定义格式实例化泛型编程 如何实现一个通用的交换函数呢&#xff1f; void Swap(int& left, int& right) {int tmp left;left right;right tmp; }void Swap(double& left, doub…

【Spring6源码・IOC】BeanDefinition的加载

哎呀&#xff0c;又是午夜时分&#xff0c;又是一个失眠的夜晚&#xff0c;和去年一样&#xff0c;记得去年今日&#xff0c;也是睡不着觉&#xff0c;就注册了csdn的账号&#xff0c;开始写东西&#xff0c;csdn真是深夜最好的安魂剂。 Spring都发布了6.0&#xff0c;这不赶紧…

2022.12青少年软件编程(Python)等级考试试卷(三级)

2022.12.10青少年软件编程(Python)等级考试试卷(三级) 一、单选题(共25题,共50分) 1.列表L1中全是整数,小明想将其中所有奇数都增加1,偶数不变,于是编写了如下图所示的代码。 请问,图中红线处,代码应该是?(D) A. x || 2 B. x ^ 2 C. x && 2 D. x %…

JS日期与字符串相互转换(时间格式化YYYY-MM-DD,Dayjs的使用)

JS日期与字符串相互转换——JS封装函数&#xff0c;Dayjs转换时间格式相关文章调用场景复现一、JS封装函数1、日期转字符串2、字符串转日期二、 Dayjs转换时间格式1、Dayjs快速安装与使用2、Dayjs格式化日期相关文章调用 文章内容文章链接JS数组对象——根据日期进行排序&…

南邮数据结构考研常用算法

1.链表 在带头结点的链表中&#xff0c;删除所有值为x的结点 void Del_X(Linklist &L,ElemType x){LNode *pL->next, *preL,*q;while (p!null){if (p->datax){qp;pp->next;pre->nextp;free(q);}else{prep;pp->next;}} }使用单链表进行插入排序 ListNode*…

数组常用方法总结 (1) :pop / push / shift / unshift

pop 从尾部删除一项。改变原有数组。返回删除掉的内容。 <template><div class"myBlock"><div class"tableBlock"><div class"title">{{ newObject ? "操作后的数组" : "操作前的数组" }}</d…

从0到1完成一个Vue后台管理项目(十、列表API封装、Table列表渲染、表格数据转换)

往期 从0到1完成一个Vue后台管理项目&#xff08;一、创建项目&#xff09; 从0到1完成一个Vue后台管理项目&#xff08;二、使用element-ui&#xff09; 从0到1完成一个Vue后台管理项目&#xff08;三、使用SCSS/LESS&#xff0c;安装图标库&#xff09; 从0到1完成一个Vu…

docker安装及安装过程中遇到的问题

安装Docker-CE 备注&#xff1a;Docker 安装&#xff0c;请参考 Docker 官⽅⽂档: Install Docker Engine on Ubuntu | Docker Documentation 也可参照如下命令进行快速安装。 Ubuntu 卸载旧版本&#xff08;视需要&#xff09; $ sudo apt-get remove docker docker-engin…

Java并发(4)- synchronized与CAS

引言 上一篇文章中我们说过&#xff0c;volatile通过lock指令保证了可见性、有序性以及“部分”原子性。但在大部分并发问题中&#xff0c;都需要保证操作的原子性&#xff0c;volatile并不具有该功能&#xff0c;这时就需要通过其他手段来达到线程安全的目的&#xff0c;在Ja…

因子图--isam相关内容总结

编辑切换为居中添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09;编辑切换为居中添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09;平方根法--通过平方根的方法&#xff0c;发现矩阵新增加的变量都会出现在最后一行。Givens旋转方法求解Ax…

Linux环境下,java调用C/C++动态库

目录 一、环境准备 1、安装gcc/g 2、下载jdk库并配置运行环境 二、配合Java程序创建C程序的动态库 1、生成要求清单 2、交给C 去实现 (1) 接口函数实现 (2) 创建动态库 (3) 检查动态库是否正常链接 3、测试&#xff1a;Java程序调用C动态库 一、环境准备 既然是同时…

百万级数据以Excel形式导出

(1).主要考虑到两个方面&#xff0c;第一个方面是内存溢出问题&#xff0c;所以选用阿里的EasyExcel因为它对POI进行了封装功能强大&#xff1b;第二个方面是由于excel版本导致Sheet存储容量不一样&#xff0c;cexcel2003(.xls)每个Sheet只能存6万多条数据而cexcel2007(xlsx)能…

【自学Python】Python布尔型(bool)

Python布尔型(bool) Python布尔型(bool)教程 Python 布尔类型也叫 bool 类型&#xff0c;Python 布尔类型取值为 True 和 False。Python bool 类型的 True 表示条件为真&#xff0c; False 表示条件为假。 Python布尔型(bool) Python 中的布尔类型可以当做 整数 来对待&…

LeetCode 287. 寻找重复数难度中等2004

&#x1f308;&#x1f308;&#x1f604;&#x1f604;欢迎来到茶色岛独家岛屿&#xff0c;本期将为大家揭晓LeetCode 287. 寻找重复数难度中等2004&#xff0c;做好准备了么&#xff0c;那么开始吧。&#x1f332;&#x1f332;&#x1f434;&#x1f434;一、题目名称LeetCo…

怎么在Gitee(码云)上传一个项目(一分钟)

目录怎么在Gitee&#xff08;码云&#xff09;上传一个项目1、工具1.1、Git1.2、新建仓库2、上传流程3、回答上传项目流程中的几个疑问&#xff1f;怎么在Gitee&#xff08;码云&#xff09;上传一个项目 1、工具 1.1、Git 在Git官网或者利用镜像下载符合自己电脑操作系统版…

小众企业在选购低代码平台时需要注意什么

编者按&#xff1a;企业个性化定制需求如何实现&#xff1f;本文介绍了小众企业在选择低代码平台需要注意的点&#xff0c;帮助企业选出更合适得的软件平台。关键词&#xff1a;源码交付&#xff0c;数据整合&#xff0c;前后端分离&#xff0c;私有化部署&#xff0c;安全技术…

IB生物笔记:细胞学说

国际学校生物老师从0开始解读IB生物&#xff0c;感兴趣的同学记得收藏哦~IB生物分为SL(standard level)和HL(higher level)SL有6个topic∶细胞生物&#xff0c;分子生物&#xff0c;遗传学&#xff0c;生态学&#xff0c;物种进化以及多样性和人体生理。HL除了上述6个topic外还…

【pat】出租

下面是新浪微博上曾经很火的一张图&#xff1a;一时间网上一片求救声&#xff0c;急问这个怎么破。其实这段代码很简单&#xff0c;index数组就是arr数组的下标&#xff0c;index[0]2 对应 arr[2]1&#xff0c;index[1]0 对应 arr[0]8&#xff0c;index[2]3 对应 arr[3]0&#…