动态规划PTA总结

news2024/10/2 22:25:06

0动态规划

最优子结构&&最值问题&&重叠子问题  --->  动态规划

引用别人的文章

1数字三角形

1.1题目

给定一个由 n行数字组成的数字三角形如下图所示。试设计一个算法,计算出从三角形
的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大。

输入格式:

输入有n+1行:

第 1 行是数字三角形的行数 n,1<=n<=100。

接下来 n行是数字三角形各行中的数字。所有数字在0..99 之间。

输出格式:

输出最大路径的值。

输入样例:

在这里给出一组输入。例如:

5 
7 
3 8 
8 1 0 
2 7 4 4
4 5 2 6 5 

输出样例:

在这里给出相应的输出。例如:

30

1.2代码

#include <bits/stdc++.h>
using namespace std;

int maxMatrix[101][101];

int main()
{
    int n;
    cin >> n;

    // 读入数据
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= i; ++j)
        {
            int temp;
            cin >> temp;
            maxMatrix[i][j] = temp;
        }
    }

    // 动态规划
    for (int i = 2; i <= n; ++i)
    {
        for (int j = 1; j <= i; ++j)
        {
            if (j == 1)
            {
                maxMatrix[i][j] += maxMatrix[i - 1][j];
            }
            else if (j == i)
            {
                maxMatrix[i][j] += maxMatrix[i - 1][j - 1];
            }
            else
            {
                maxMatrix[i][j] += maxMatrix[i - 1][j - 1] > maxMatrix[i - 1][j] ? maxMatrix[i - 1][j - 1] : maxMatrix[i - 1][j];
            }
        }
    }

    // 找出最大值
    int max = maxMatrix[n][1];
    for (int i = 2; i <= n; ++i)
    {
        if (maxMatrix[n][i] > max)
        {
            max = maxMatrix[n][i];
        }
    }

    cout << max;
    return 0;
}

1.3总结 

最优子结构:通过n-1行数字三角形中每条路径的数字总和可以得出n行数字三角形中每条路径的数字总和。

最值问题:通过数字三角形中每条路径的数字总和,可以挑出数字总和最大的值。

重叠子问题:样例中以第5行第一个数和第5行第二个数为末尾的路径的数字总和的计算都会用到以第4行第一个数为末尾的路径的数字总和。

dp[i][j]二维数组:表示以第i行第j个数为末尾的路径的最大数字总和。

遍历顺序:遍历的终点是把第n行的所有数字全部遍历完。

代码思路

  1. 数字三角形行数存入n中,数字三角形的元素值存入maxMatrix中,maxMatrix同时也表示dp二维数组。
  2. 正向遍历,如果第i行第j个数是本行第一个数,那么maxMatrix[i][j]就等于maxMatrix[i][j]+maxMatrix[i-1][j];如果是本行最后一个数,那么maxMatrix[i][j]就等于maxMatrix[i][j]+maxMatrix[i-1][j-1];否则,maxMatrix[i][j]等于maxMatrix[i][j]加上maxMatrix[i-1][j-1]和maxMatrix[i-1][j]中更大的数。
  3. 遍历第n行的maxMatrix,找出最大值。

2最长公共子序列

2.1题目

现在给你两个由AGCT四个字母构成的字符串,请你求出两个DNA序列的最长公共子序列。

输入格式:

两行,每行一个字符串,分别表示一个DNA序列(每个字符串长度不超过1000)。

输出格式:

一个数,最长公共子序列元素的个数。

输入样例:

在这里给出一组输入。例如:

AGCT
ATT

输出样例:

在这里给出相应的输出。例如:

2

2.2代码

#include <bits/stdc++.h>
using namespace std;
int maxLen[1001][1001];

int main()
{
    string s1, s2;
    cin >> s1 >> s2;

    for (int i = 1; i <= s1.length(); ++i)
    {
        for (int j = 1; j <= s2.length(); ++j)
        {
            if (s1[i] == s2[j])
            {
                maxLen[i][j] = maxLen[i - 1][j - 1] + 1;
            }
            else
            {
                maxLen[i][j] = maxLen[i - 1][j] > maxLen[i][j - 1] ? maxLen[i - 1][j] : maxLen[i][j - 1];
            }
        }
    }

    cout << maxLen[s1.length()][s2.length()];
    return 0;
}

2.3总结

最优子结构:通过s1[0-i]和s2[0-j]的最长公共子序列长度可以得出s1[0-(i+1)]和s2[0-(j+1)]的最长公共子序列长度。

最值问题:两个字符串的最长公共子序列就是dp[s1.length][s2.length]的值。

重叠子问题:dp[i][j]会在求dp[i+1][j+1]和dpdp[i+1][j]和dp[i][j+1]时用到。

dp[i][j]二维数据:表示s1[0~i]和s2[0~j]的最长公共子序列长度。

遍历顺序:遍历的终点是dp[s1.length][s2.length]。

代码思路

  1. s1和s2用来存储两个字符串,maxLen二维数组表示dp二维数组。
  2. 正向遍历,如果s1[i]==s2[j],那么maxLen[i][j]=maxLen[i-1][j-1]+1;否则,maxLen[i][j]=maxLen[i][j-1]和maxLen[i-1][j]的较大值。
  3. maxLen[s1.length][s2.length]即为两个字符串的最长公共子序列长度。

注意

公共子序列和公共子串:公共子序列可以不连续,公共子串必须连续。 

3单调递增最长子序列

3.1题目

设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。

输入格式:

输入有两行:
第一行:n,代表要输入的数列的个数
第二行:n个数,数字之间用空格格开

输出格式:

最长单调递增子序列的长度

输入样例:

在这里给出一组输入。例如:

5
1 3 5 2 9

输出样例:

在这里给出相应的输出。例如:

4

3.2代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin >> n;
    int array[100001];
    for (int i = 0; i < n; ++i)
    {
        cin >> array[i];
    }

    int maxLen[100001];
    for (int i = 0; i < n; ++i)
    {
        maxLen[i] = 1;
    }

    int max = maxLen[0];
    for (int i = 1; i < n; ++i)
    {
        for (int j = 0; j < i; ++j)
        {
            if (array[i] > array[j] && maxLen[i] >= maxLen[j])
            {
                maxLen[i] = maxLen[j] + 1;
                max = maxLen[i] > max ? maxLen[i] : max;
            }
        }
    }

    cout << max;
    return 0;
}

3.3总结

最优子结构:通过以第i个数结尾的单调递增子序列的长度可以得出以第j个数结尾的单调递增子序列的长度(j>i,第j个数是第一个比第i个数大的数)。

最值问题:比较n个最长单调递增子序列的长度,挑出最长的。

重叠子问题:第i个数结尾的单调递增子序列的长度会被多次用到。

dp[i]一维数组:用来表示以第i个数字结尾的最长单调递增子序列的长度。

遍历顺序: 遍历的终点是把所有i遍历完。

代码思路: 

  1. n存入序列长度,array一维数组存放序列元素,maxLen一维数组表示dp数组,初始化为1(元素本身长度为1)。
  2. max表示当前最长单调递增子序列长度。遍历这n个序列元素,对于每一个元素,都要遍历其前面的每一个元素,找出前面的小于自己的元素中最长单调子序列的长度,然后加1,赋给自己。
  3. 输出max。

4最大子段和

4.1题目

给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。

要求算法的时间复杂度为O(n)。

输入格式:

输入有两行:

第一行是n值(1<=n<=10000);

第二行是n个整数。

输出格式:

输出最大子段和。

输入样例:

在这里给出一组输入。例如:

6
-2 11 -4 13 -5 -2

输出样例:

在这里给出相应的输出。例如:

20

4.2代码

#include <bits/stdc++.h>
using namespace std;

int n;
int maxSum[10001];

int main()
{
    cin >> n;
    int array[10001];
    int max = 0;
    for (int i = 1; i <= n; ++i)
    {
        cin >> array[i];
        maxSum[i] = array[i] + (maxSum[i - 1] > 0 ? maxSum[i - 1] : 0);
        max = maxSum[i] > max ? maxSum[i] : max;
    }

    cout << max;
    return 0;
}

4.3总结

最优子结构:通过以a[i]结尾的最大子段和可以得出以a[i+1]结尾的最大子段和。

最值问题:在所有的以a[i]结尾的最大子段和中找出最大值。

重叠子问题:求dp的过程中要用到,最终求最值也要用到。

dp[i]一维数组:表示以a[i]结尾的最大子段和。

遍历顺序: 遍历的终点是把所有的以a[i]结尾的最大子段和都求出来。

代码思路: 

  1. n存储序列元素个数,array数组存储序列元素,maxSum表示dp。
  2. 正向遍历,如果maxSum[i]大于0,那么maxSum[i+1]=maxSum[i]+array[i];否则,maxSum[i]=array[i]。max用来表示当前的最大子段和。
  3. 输出最大子段和。

5最大子矩阵和

5.1题目

最大子矩阵和问题。给定m行n列的整数矩阵A,求矩阵A的一个子矩阵,使其元素之和最大。

输入格式:

第一行输入矩阵行数m和列数n(1≤m≤100,1≤n≤100),再依次输入m×n个整数。

输出格式:

输出第一行为最大子矩阵各元素之和,第二行为子矩阵在整个矩阵中行序号范围与列序号范围。

输入样例1:

5 6
60 3 -65 -92 32 -70
-41 14 -38 54 2 29
69 88 54 -77 -46 -49
97 -32 44 29 60 64
49 -48 -96 59 -52 25

输出样例1:

输出第一行321表示子矩阵各元素之和,输出第二行2 4 1 6表示子矩阵的行序号从2到4,列序号从1到6

321
2 4 1 6

5.2代码

#include <bits/stdc++.h>
using namespace std;

int m, n;

int *getMaxSum(int *array)
{
    int dp[102][2] = {{0, 0}};
    int max = array[0];
    int begin = 1, end = 1;
    for (int i = 1; i <= n; ++i)
    {
        if (dp[i - 1][0] > 0)
        {
            dp[i][0] = dp[i - 1][0] + array[i - 1];
            dp[i][1] = dp[i - 1][1] + 1;
        }
        else
        {
            dp[i][0] = array[i - 1];
            dp[i][1] = 1;
        }
        if (dp[i][0] > max)
        {
            max = dp[i][0];
            end = i;
            begin = i - dp[i][1] + 1;
        }
    }

    // for (int i = 1; i <= n; ++i)
    // {
    //     cout << endl;
    //     cout << "dp[" << i << "][0] = " << dp[i][0] << " ";
    // }
    // cout << endl;

    int *result = new int[3];
    result[0] = max;
    result[1] = begin;
    result[2] = end;
    return result;
}

int *getResultArray(int array[][101], int hangShu)
{
    int *result = new int[102];
    for (int i = 0; i < n; ++i)
    {
        result[i] = 0;
    }

    for (int i = 0; i < hangShu; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            result[j] += array[i][j];
        }
    }

    return result;
}

int main()
{
    int matrix[101][101];
    cin >> m >> n;
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            cin >> matrix[i][j];
        }
    }

    int *result = getMaxSum(matrix[0]);
    int max = result[0];
    int hangBegin = 1, hangEnd = 1, lieBegin = result[1], lieEnd = result[2];
    for (int i = 1; i <= m; ++i)
    {
        for (int j = 0; j <= m - i; ++j)
        {
            int *temp = getMaxSum(getResultArray(matrix + j, i));
            if (temp[0] > max)
            {
                // cout << "yes" << endl;
                max = temp[0];
                hangBegin = j + 1;
                hangEnd = hangBegin + i - 1;
                lieBegin = temp[1];
                lieEnd = temp[2];
            }
        }
    }

    cout << max << endl;
    cout << hangBegin << " " << hangEnd << " " << lieBegin << " " << lieEnd;
    return 0;
}

5.3总结

代码思路: 

  1. m存储行数,n存储列数,matrix存储矩阵元素。
  2. 处理行宽为1的矩阵(序列),记录最大值;处理行宽为2的矩阵(两个一维序列的对应位相加->一个一维序列),记录最大值......
  3. 输出最大值。

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

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

相关文章

HTML+CSS美食静态网页设计——简单牛排美食餐饮(9个页面)公司网站模板企业网站实现

&#x1f468;‍&#x1f393;静态网站的编写主要是用HTML DIVCSS JS等来完成页面的排版设计&#x1f469;‍&#x1f393;,常用的网页设计软件有Dreamweaver、EditPlus、HBuilderX、VScode 、Webstorm、Animate等等&#xff0c;用的最多的还是DW&#xff0c;当然不同软件写出的…

SAP MM 为UB类型的STO执行VL10B,报错-没有项目类别表存在(表T184L NL 0002 V)-之对策

SAP MM 为UB类型的STO执行VL10B&#xff0c;报错-没有项目类别表存在&#xff08;表T184L NL 0002 V)-之对策 业务人员创建好了UB类型的转储单据后&#xff0c;试图执行事务代码VL10B&#xff0c;未能成功&#xff0c;报错如下&#xff1a; 报错信息&#xff1a;4500000246 00…

【数据结构】——带头双向循环链表

目录 1.带头双向循环链表 2.链表实现 2.1可完成带头双向可循环链表节点的结构体 2.2申请一个可双向循环的节点 2.3初始化链表 2.4尾插 2.5尾删 2.6头插 2.7头删 2.8打印 2.9查找&#xff08;修改&#xff09; 2.10在pos之前插入x 2.11删除pos位置 2.12判空 2.13记…

Springboot图书馆管理系统毕业设计、Springboot图书借阅系统设计与实现 毕设作品参考

功能清单 【后台管理员功能】 广告管理&#xff1a;设置小程序首页轮播图广告和链接 留言列表&#xff1a;所有用户留言信息列表&#xff0c;支持删除 会员列表&#xff1a;查看所有注册会员信息&#xff0c;支持删除 资讯分类&#xff1a;录入、修改、查看、删除资讯分类 录入…

【毕业设计源码】基于微信小程序的校园第二课堂(课外活动)管理系统

该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等学习内容。 目录 一、项目介绍&#xff1a; 二、文档学习资料&#xff1a; 三、模块截图&#xff1a; 四、开发技术与运行环境&#xff1a; 五、代码展示&#xff1a; 六、数据库表截图&#xff1a…

【数据库原理及应用】——数据库设计(学习笔记)

&#x1f4d6; 前言&#xff1a;数据库的设计是指基于现有的数据库管理系统&#xff0c;针对具体应用构建适合的数据库逻辑模式和物理结构&#xff0c;并据此建立数据库及其应用系统&#xff0c;使之能有效地存储和管理数据&#xff0c;满足各类用户的应用需求。本章将介绍数据…

PaddleOCR简单使用教程-Windows

说明 最近公司业务需要用到图文识别类似的功能&#xff0c;所以查阅了许多工具之后选择用百度开源的PaddleOCR来进行使用 先看官方简介: 百度飞桨PaddleOCR旨在打造一套丰富、领先、且实用的OCR工具库&#xff0c;助力开发者训练出更好的模型&#xff0c;并应用落&#xff0c;支…

Flink系列之Flink 流式编程模式总结

title: Flink系列 一、Flink 流式编程模式总结 1.1 基础总结 官网&#xff1a; https://flink.apache.org/ Apache Flink — Stateful Computations over Data Streams 三个任意&#xff1a; 任意的数据源 Source任意的计算类型 Transformation任务的数据目的地 Sink其中关于…

trt多流、多batch、多context

&#xff08;1&#xff09;一个engine可以创建多个context&#xff0c;一个engine可以有多个执行上下文&#xff0c;允许一组权值用于多个重叠推理任务。例如&#xff0c;可以使用一个引擎和一个上下文在并行CUDA流中处理图像。每个上下文将在与引擎相同的GPU上创建。 &#xf…

跨境电商市场也“内卷”,出海卖家如何破圈?

近些年来&#xff0c;跨境电商从业者都在调侃本行业越来越“卷”&#xff0c;大家需要铆足了劲竞争更有利的资源&#xff0c;以往的流量红利期似乎一去不复返了。事实上&#xff0c;很多跨境电商卖家对这种局势并不陌生&#xff0c;一些人甚至经历了国内电商从流量红利期至流量…

复习计算机网络——第三章记录(1)

数据链路层 功能&#xff1a;通过一些数据链路层的协议&#xff0c;在不太可靠的物理链路上实现可靠的数据传输。 相关基本概念&#xff1a; 1、结点&#xff08;node&#xff09;&#xff1a;网络中的主机&#xff08;host&#xff09;和路由器&#xff08;router&#xff…

JS实现简易计算器(input表单)

实现效果: 代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"></head><body><p>整数1:<input type"text" id"num1"></p><p>整数2:<input type"text&q…

Kamiya丨Kamiya艾美捷抗BCMA单抗,克隆Vicky-2说明书

Kamiya艾美捷抗BCMA单抗化学性质&#xff1a; 同义词&#xff1a;B细胞成熟蛋白&#xff0c;TNFRSF 17&#xff0c;CD269。 特异性&#xff1a;识别鼠标BCMA。 物种反应性&#xff1a;老鼠不与人BCMA发生交叉反应。其他物种未经测试。 Ig同种型&#xff1a;大鼠IgG2a 免疫…

4×30m钢筋混凝土简支T梁桥结构设计与计算

目 录 1设计资料 1 1.1桥面净宽 1 1.2设计荷载 1 1.3主梁跨径和全长 1 1.4材料 1 1.5设计依据 1 1.6参考资料 1 2任务与要求 2 2.1结构尺寸拟定 2 2.2行车道板计算 2 2.3主梁计算 2 2.4横梁的计算 2 3结构尺寸拟定 3 4行车道板计算 4 4.1永久荷载及其效应 4 4.2截面设计、配筋与…

机器视觉计算(一)

本文主要记录像素尺寸映射到实际物理尺寸的计算&#xff0c;并给出一些参考文献。 分辨率 视野(Field of View)/像素(Pixel) 比如我要看的产品大小是30mm*10MM&#xff0c;使用200万像素&#xff08;1600pixel*1200pixel&#xff09;的相机。因为产品是长条形&#xff0c;为了…

[附源码]Python计算机毕业设计SSM酒店客户管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

read-after-write consistency 写后读一致性的解决方法

问题定义 写后读一致即写完数据之后马上读&#xff0c;直接能读到新的数据&#xff0c;而不是老的数据。 导致这个问题主要是数据库之间的同步延时。这里只讨论一主多从的情况。 如下图&#xff1a; 用户添加新评论用户刷新&#xff0c;读请求到从节点1&#xff0c;此时从节…

【Matplotlib绘制图像大全】(十三):甜甜圈饼图

前言 大家好,我是阿光。 本专栏整理了《Matplotlib绘制图像大全》,内包含了各种常见的绘图方法,以及Matplotlib各种内置函数的使用方法,帮助我们快速便捷的绘制出数据图像。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmMatp…

Vue2.0开发之——Vue基础用法-vue-cli(30)

一 概述 vue-cli—介绍并安装vue-clivue-cli—基于vue-cli创建vue项目vue-cli—项目预览效果vue-cli—项目目录结构vue-cli—vue项目运行过程vue-cli—组件的基本使用 二 vue-cli—介绍并安装vue-cli 2.1 什么是单页面应用程序 单页面应用程序&#xff08;英文名&#xff1a…

C语言刷题系列——6.(递归)实现顺序输出整数

递归实现顺序输出整数 ❄️一) 题目要求☃️1.函数接口定义&#xff1a;☃️2.裁判测试程序样例&#xff1a;❄️二) 非递归 解法☃️step1.统计位数☃️step2.循环&#xff0c;打印每一位☃️step3.实现❄️三) 递归 解法☃️step1.分析☃️step2.图解流程☃️step3.实现)❄️…