acwing算法基础之动态规划--DP习题课1

目录

  • 1 基础知识
  • 2 模板
  • 3 工程化

1 基础知识

暂无。。。

2 模板

暂无。。。

3 工程化

题目1:最长上升子序列,要求时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

解题思路:保存每个长度下的最小的结尾元素值,遍历数组元素时,通过二分找到它,然后更新它即可,返回len。

C++代码如下,

#include <iostream>using namespace std;const int N = 1e5 + 10;
int n;
int a[N];
int q[N];int main() {cin >> n;for (int i = 0; i < n; ++i) cin >> a[i];int len = 0;q[0] = -2e9;for (int i = 0; i < n; ++i) {//在q中找到<a[i]的最后一个元素int l = 0, r = len;int res = -1;while (l <= r) {int mid = l + r >> 1;if (q[mid] < a[i]) {res = mid;l = mid + 1;} else {r = mid - 1;}}q[res + 1] = a[i];len = max(len, res + 1);}cout << len << endl;return 0;
}

题目2:最小编辑距离。有三种操作,插入、删除和替换,求将字符串a变成字符串b的最小操作次数。

解题思路:DP,考虑最后一次操作次数。

状态定义,f[i][j]:将字符串a的前i位变为字符串b的前j位的最小操作次数。

状态转移,有

  1. 最后一次操作是插入操作,则说明操作前已经匹配了字符串b的前j-1位,故f[i][j - 1] + 1
  2. 最后一次操作是删除操作,则说明操作前字符串a的前i-1位已经匹配了字符串b的前j位,故f[i - 1][j] + 1
  3. 最后一次操作是替换操作,则说明操作前字符串a的前i-1位已经匹配了字符串b的前j-1位,但可能a[i] == b[j],则f[i - 1][j - 1];否则f[i - 1][j - 1] + 1

初始化,f[i][0]表示将a的前i位变成b的前0位,则值为if[0][j]表示将a的前0位变成b的前j位,则值为j

最终答案,f[n][m]

C++代码为,

#include <iostream>using namespace std;const int N = 1010;
int n, m;
char a[N], b[N];
int f[N][N];int main() {cin >> n >> a + 1;cin >> m >> b + 1;for (int i = 0; i <= n; ++i) f[i][0] = i;for (int j = 0; j <= m; ++j) f[0][j] = j;for (int i = 1; i <= n; ++i) {for (int j = 1; j <= m; ++j) {f[i][j] = min(f[i-1][j] + 1, f[i][j-1] + 1);if (a[i] == b[j]) f[i][j] = min(f[i][j], f[i-1][j-1]);else f[i][j] = min(f[i][j], f[i-1][j-1] + 1);}}cout << f[n][m] << endl;return 0;
}

题目3:编辑距离。

思路:就是将题目2的实现套用过来,调用多次即可。

C++代码如下,

#include <iostream>
#include <cstring>using namespace std;const int N = 1010, M = 20;
int n, m;
char str[N][M];
int f[M][M];int get_dis(char a[], char b[]) {int la = strlen(a + 1), lb = strlen(b + 1);for (int i = 0; i <= la; ++i) f[i][0] = i;for (int j = 0; j <= lb; ++j) f[0][j] = j;for (int i = 1; i <= la; ++i) {for (int j = 1; j <= lb; ++j) {f[i][j] = min(f[i-1][j] + 1, f[i][j-1] + 1);f[i][j] = min(f[i][j], f[i-1][j-1] + (a[i] != b[j]));}}return f[la][lb];
}int main() {cin >> n >> m;for (int i = 1; i <= n; ++i) cin >> str[i] + 1;for (int j = 1; j <= m; ++j) {int limit;char b[20];cin >> b + 1 >> limit;int res = 0;for (int i = 1; i <= n; ++i) {if (get_dis(str[i], b) <= limit) res += 1;}cout << res << endl;}return 0;
}

题目4:整数划分问题。给定整数 n n n,求有多少种划分方案。比如31+1+11+23这3种划分方案。

思路:它属于计数类DP。

(解法一)

状态定义,f[i][j]:从前i个数中选,总和为j的方案数。

考虑最后一次选法,状态转移,有,

  1. 不选第i个数,即f[i-1][j]
  2. 选1个第i个数,即f[i-1][j-i]
  3. 选2个第i个数,即f[i-1][j - 2 * i]
    ……
  4. 选s个第i个数,即f[i-1][j - s * i]

故,综合上述,f[i][j]状态转移为,

f[i][j] = f[i-1][j] + f[i-1][j-i] + f[i-1][j - 2 * i] + f[i-1][j - 3 * i] + ... + f[i-1][j - s * i]

考虑状态f[i][j-i]的状态转移,有

f[i][j-i] = f[i-1][j-i] + f[i-1][j - 2 * i] + f[i-1][j - 3 * i] + ... + f[i-1][j - s * i]

f[i][j]的状态转移可以写成,

f[i][j] = f[i-1][j] + f[i][j-i]

初始化,f[0][0] = 1

同时利用滚动数组优化,可以有如下C++代码,

#include <iostream>using namespace std;const int N = 1010, mod = 1e9 + 7;
int n;
int f[N];int main() {cin >> n;f[0] = 1;for (int i = 1; i <= n; ++i) {for (int j = i; j <= n; ++j) {f[j] = (f[j] + f[j-i]) % mod;}}cout << f[n] << endl;return 0;
}

(解法二)
状态表示f[i][j]:总和是i,有j个数,的所有方案数。

f[i][j]的状态转移,有,

  1. 拆分出来的数的最小值是1,即·f[i-1][j-1]
  2. 拆分出来的数的最小值大于1,即f[i-j][j]

f[i][j]的状态转移为,

f[i][j] = f[i-1][j-1] + f[i-j][j]

初始化,f[0][0] = 1

最终答案,f[n][1] + f[n][2] + ... + f[n][n]

C++代码如下,

#include <iostream>using namespace std;const int N = 1010, mod = 1e9 + 7;
int n;
int f[N][N];int main() {cin >> n;f[0][0] = 1;for (int i = 1; i <= n; ++i) {for (int j = 1; j <= i; ++j) {f[i][j] = (f[i-1][j-1] + f[i-j][j]) % mod;}}int res = 0;for (int j = 1; j <= n; ++j) res = (res + f[n][j]) % mod;cout << res << endl;return 0;
}

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

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

相关文章

hadoop源码解读

一、hadoop rpc总结 1、RPC指的是不同进程的方法调用&#xff0c;分为客户端和服务端&#xff0c;客户端调用服务端的方法&#xff0c;方法的执行在服务端。 2、如何实现Hadoop RPC的调用&#xff0c;必须要实现协议&#xff0c;这个协议其实就是一个接口&#xff0c;但是这个…

【Android Jetpack】Room数据库

文章目录 引入EntitiesPrimary Key主键索引和唯一性对象之间的关系外键获取关联的Entity对象嵌套对象Data Access Objects&#xff08;DAOs&#xff09;使用Query注解的方法简单的查询带参数查询返回列的子集可被观察的查询 数据库迁移用法 引入 原始的SQLite有以下两个缺点: …

LCD屏接口与模式详解:干货超多

前言 随着时代的发展&#xff0c;现如今我们生活上已经随处可见的各种电子产品了&#xff0c;诸如手机、平板、电脑、一些其它智能单品上都有用到显示屏&#xff0c;它作为人机交互的重要桥梁之一&#xff0c;我认为它是生活中必不可少的存在&#xff0c;如果少了它&#xff0c…

【Electron】上下键切换消息

需求&#xff1a; 如图&#xff0c;需要监听上下键切换消息 Electron 注册 全局快捷键【globalShortcut】监听 在focus注册 在blur 注销 如苹果系统在使用某个软件(focus)时 右上角会有应用标题 Electron 代码&#xff1a; win.on(focus, ()>{globalShortcut.register(U…

物联网边缘计算是什么?如何实现物联网边缘计算?

物联网边缘计算是一种在物联网设备和网络中实施计算和数据处理的技术。它允许在物联网设备或网络边缘进行数据分析和处理&#xff0c;而不需要将所有数据传输到远程数据中心或云端进行处理。物联网边缘计算将计算和数据处理的能力迁移到物联网设备的边缘&#xff0c;使得设备能…

如何群发发票邮件内容

群发发票邮件内容需要仔细考虑邮件的主题、正文和附件内容&#xff0c;以确保邮件的准确性和完整性。以 一、明确邮件目的 在群发发票邮件时&#xff0c;首先需要明确邮件的目的。一般来说&#xff0c;发票邮件的目的是向客户或供应商提供交易的详细记录和证明。因此&#xf…

啊哒-MISC-bugku-解题步骤

——CTF解题专栏—— 题目信息&#xff1a; 题目&#xff1a;啊哒 作者&#xff1a;第七届山东省大学生网络安全技能大赛 提示&#xff1a;无 解题附件&#xff1a; 解题思路&#xff1a; 图片的话还是老三样斧winwalk、010Editor、Stegsolve。ok直接开搞&#xff01; 解题…

基于UDP的TFTP文件传输

代码&#xff1a; #include <myhead.h>//实现下载功能 int download(int cfd,struct sockaddr_in sin) {char buf[516] ""; //定义资源包char fileName[128] ""; //定义文件名printf("请输入文件名:");scanf("%s",fileName…

Re0: 从零实现一个置顶任意窗口的小工具

前言 话不多说&#xff0c;先上效果&#xff1a; 这里展示的是通过下拉框选择窗口&#xff0c;让窗口显示并置顶&#xff0c;其实还可以直接通过快捷键&#xff08;先鼠标点击要置顶的窗口&#xff0c;再使用CTRLSHIFTT&#xff09;&#xff0c;本文涉及到的完整代码已上传到G…

【JavaEE初阶】 HTTP 请求 (Request)详解

文章目录 &#x1f340;序言&#x1f384;认识URL&#x1f6a9;URL 基本格式&#x1f6a9;query string&#x1f6a9;关于 URL encode &#x1f334;认识 "方法" (method)&#x1f6a9;GET方法&#x1f6a9;POST 方法&#x1f6a9; GET 和 POST 的区别 &#x1f38b;…

Java后端开发——JDBC(万字详解)

Java后端开发——JDBC&#xff08;万字详解&#xff09; 今日目标 掌握JDBC的的CRUD理解JDBC中各个对象的作用掌握Druid的使用 1&#xff0c;JDBC概述 在开发中我们使用的是java语言&#xff0c;那么势必要通过java语言操作数据库中的数据。这就是接下来要学习的JDBC。 1.1 …

【Axure高保真原型】区间评分条

今天和大家分享区间评分条的原型模板&#xff0c;我们可以左右拖动移动滑块到指定位置&#xff0c;评分条上方会根据两个滑块所在的位置&#xff0c;自动计算出对应的区间范围&#xff1b;这个原型模板使用也很简单&#xff0c;只需要在里面填写区间的最大值&#xff0c;即可自…

纯前端实现导入excel数据

准备工作 - 下载 xlsx npm install xlsx下面直接上代码&#x1f447; <template><div><input type"file" accept".xlsx, .xls" change"handleClick"></div> </template><script langts setup> import * a…

24.有哪些生命周期回调方法?有哪几种实现方式?

有哪些生命周期回调方法?有哪几种实现方式? 有两个重要的bean 生命周期方法, 第一个是init , 它是在容器加载bean的时候被调用。第二个方法是 destroy 它是在容器卸载类的时候被调用。bean 标签有两个重要的属性(init-method和destroy-method)。用它们你可以自己定制初始…

盛最多水的容器-中等

leetcode链接 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不能倾…

JS之Object.defineProperty方法

给对象添加属性的方法有许多&#xff0c;这次让我为大家介绍一种给对象添加属性的静态方法吧&#xff01; 语法&#xff1a;Objcet.defineProperty(对象的名称&#xff0c;“添加的键名”&#xff0c;{value&#xff1a;键值}) const obj {name:"张三",age:18}// 我…

Typora .MD笔记中本地图片批量上传到csdn (.PNG格式)(无需其他任何图床软件)

Typora .MD笔记中本地图片批量上传到csdn &#xff08;.PNG格式&#xff09;(无需其他任何图床软件) 截图软件推荐 qq 截图 快捷键 ctrlshiftA. 步骤一 设置Typora 的图片 点击文件. 点击偏好设置 ->图像 我们可以选择将图片复制到我们的文件夹中。 建议刚写好文件标题就…

C#键盘钩子(Hook)拦截器的使用

引言 键盘钩子(Hook)是一种机制&#xff0c;允许程序捕获和处理操作系统中的键盘输入。在C#中&#xff0c;我们可以使用键盘钩子来创建一个拦截器&#xff0c;用于拦截特定的键盘事件并执行自定义操作。本文将介绍如何使用C#开发一个键盘钩子拦截器&#xff0c;并给出一些示例代…

算法中的时间复杂度,空间复杂度

一、前言 算法&#xff08;Algorithm&#xff09;是指用来操作数据、解决程序问题的一组方法。对于同一个问题&#xff0c;使用不同的算法&#xff0c;也许最终得到的结果是一样的&#xff0c;但在过程中消耗的资源和时间却会有很大的区别 衡量不同算法之间的优劣主要是通过时…

离线环境下使用百度地图(展示自己的地图瓦片)3.0版本api

案例: 设置覆盖物标注提示文字: <script>// 百度地图API功能var map new BMap.Map("map",{ mapType: BMAP_HYBRID_MAP }); var point new BMap.Point(120.55294, 41.665515); // 创建Map实例map.centerAndZoom(point, 18); // 初始化地图,设置中心点坐标…