【题解】2023 DTS算法竞赛集训 第1次

比赛地址:https://www.luogu.com.cn/contest/143650

P1319 压缩技术

https://www.luogu.com.cn/problem/P1319
简单的签到模拟题

#include <iostream>//c++标准库
using namespace std;
int main(){int a,n,t=0,i=0,b,s=0;//t判断有没有回车,i判断输出什么,s判断有没有输完cin>>n;while(s<n*n){cin>>a;//循环输入a;i++;for(b=a;b>=1;b--){if(t==n){cout<<endl;t=0;}//判断是否需要回车,回车后t要清零if(i%2==1)cout<<0;else cout<<1;//判断是否i不被2整除,输出0,否则输出1,注意不要回车t++;s++;//t与s加一}}cout<<endl;return 0;
}

P8598 [蓝桥杯 2013 省 AB] 错误票据

https://www.luogu.com.cn/problem/P8598
这道题是判断输入的数字是否连续和重复的,那肯定是要让数字从小到大排序才能找到中断和重复数字。那排序复杂度最少是O(nlgn),是否有更快的方法?

因为输入的数字不是按照大小排序的,非常自然的想到哈希表去处理。用哈希表h记录出现的数字的次数,最后去遍历,如果出现了0次,说明中断了,如果出现了1次以上,说明重复了。

题目中给的数据范围是:正整数(不大于 1 0 5 10^5 105),因此哈希表的大小是1e5 + 5

另外要注意,如果从头遍历哈希表,前面可能有许多0,要判断更多的情况,因此可以记录下输入的最大值amax和最小值amin,在这个边界[amin,amax]里去找0和大于1的值对应的下标。

#include<bits/stdc++.h>
using namespace std;const int K = 1e5 + 5;
int h[K];
int main() {int N;cin >> N;int amin = 1e5;int amax = 0;int m, n; int x;while (N--) {while (cin >> x) {if (++h[x] > 1) n = x;amin = min(amin, x);amax = max(amax, x);}}for (int i = amin; i <= amax; i++) {if (h[i] == 0) m = i;}cout << m << " " << n;return 0;
}

P1115 最大子段和

https://www.luogu.com.cn/problem/P1115
一道经典的考研及面试题,有许多解法

要求找出连续字串的最大和,那就需要确定左右区间[l,r],再计算这个区间和。

1.暴力

我们要枚举所有情况,也就是枚举出所有的区间情况,那么l取值是[0,len(s))r取值是[i,len(s)),两层for循环。确定区间后,还要遍历区间所有数字计算和,那么整体的复杂度就是O(n^3)。这个复杂度非常高。

2.前缀和

上面的暴力求解中,第三步计算区间和,我们理所当然的对应前缀和的知识点,可以用前缀和通过O(1)的时间去计算区间所有数字计算和。

#include<bits/stdc++.h>
using namespace std;int maxSubarraySum(vector<int>& nums) {int n = nums.size();vector<int> prefixSum(n + 1, 0); // 前缀和数组,prefixSum[i]表示前i个元素的和for (int i = 1; i <= n; i++) {prefixSum[i] = prefixSum[i - 1] + nums[i - 1];}int maxSum = INT_MIN; // 最大和for (int i = 0; i < n; i++) {for (int j = i + 1; j <= n; j++) {int sum = prefixSum[j] - prefixSum[i]; // 计算从第i个元素到第j个元素的和maxSum = max(maxSum, sum);}}return maxSum;
}int main() {int n;cin >> n;vector<int> nums(n);for (int i = 0; i < n; i++) {cin >> nums[i];}int maxSum = maxSubarraySum(nums);cout << maxSum;return 0;
}

但是用前缀和虽然把时间复杂度降到了O(n^2),但是依旧有的测试点过不了,我们还需要复杂度更低的代码。

在这里插入图片描述

3.贪心

考虑更低的复杂度,我们思考如何用O(n)的时间解决,也就是遍历一遍这个数组。

采用贪心的思想,记录最大和maxSum(当前为止最大的子串和)和当前和currentSum(当前为止选择的连续子串和)

遍历每个数时更新这两个变量。maxSum=max(maxSum,currentSum)这个没什么好说的。在更新currentSum时,如果 c u r r e n t S u m < 0 currentSum<0 currentSum<0,就说明从之前的起点 l l l到当前下标 i i i这段 [ l , i ] [l,i] [l,i]的和 s u m [ l , i ] < 0 sum_{[l,i]}<0 sum[l,i]<0。往后再加后面的数字 a [ i + 1 ] a[i+1] a[i+1]时,如果 l l l不变,有 s u m [ l , i ] + a [ i + 1 ] < a [ i + 1 ] sum_{[l,i]}+a[i+1]<a[i+1] sum[l,i]+a[i+1]<a[i+1],那我们肯定是要舍弃 [ l , i ] [l,i] [l,i]这一段的,从 i + 1 i+1 i+1开始重新计算,也就是令 l = i + 1 , c u r r e n t S u m = 0 l=i+1, currentSum=0 l=i+1,currentSum=0

#include<bits/stdc++.h>
using namespace std;int maxSubarraySum(vector<int>& nums) {int n = nums.size();int maxSum = INT_MIN; // 最大和int currentSum = 0; // 当前和for (int i = 0; i < n; i++) {currentSum += nums[i];if (currentSum > maxSum) {maxSum = currentSum;}if (currentSum < 0) {currentSum = 0;}}return maxSum;
}int main() {int n;cin >> n;vector<int> nums(n);for (int i = 0; i < n; i++) {cin >> nums[i];}int maxSum = maxSubarraySum(nums);cout << maxSum;return 0;
}

降低复杂度之后可以通过全部的样例点。

在这里插入图片描述

4.动态规划

另一种思路是动态规划。

可以令 d p [ i ] dp[i] dp[i]表示:以 i i i结尾的连续子串最大和。

那么考虑所有的情况,结果应该是: r e s = m a x 1 ≤ i ≤ n d p [ i ] res=max_{1\leq i \leq n} dp[i] res=max1indp[i]

重点是状态转移方程。遍历到 i i i时,因为要求区间连续,只有两种情况:用 [ l , i − 1 ] [l,i-1] [l,i1]和不用 [ l , i − 1 ] [l,i-1] [l,i1]。如果用的话,那新的区间是 [ l , i ] [l,i] [l,i];如果不用,那新的区间是 [ i , i ] [i,i] [i,i]。因此有: d p [ i ] = m a x ( d p [ i − 1 ] + a [ i ] , a [ i ] ) dp[i] = max(dp[i-1]+a[i],a[i]) dp[i]=max(dp[i1]+a[i],a[i])

另外由于 d p [ i ] dp[i] dp[i]只跟 d p [ i − 1 ] dp[i-1] dp[i1]有关,dp数组可以用滚动数组优化空间。

时间复杂度是 O ( n ) O(n) O(n),空间复杂度是 O ( 1 ) O(1) O(1),与贪心相同。

#include<bits/stdc++.h>
using namespace std;int main() {int n;cin >> n;int ans = INT_MIN;int dp = 0;for (int i = 1; i <= n; i++) {int x;cin >> x;dp = max(x, dp + x);ans = max(ans, dp);}cout << ans;return 0;
}

P1002 [NOIP2002 普及组] 过河卒

https://www.luogu.com.cn/problem/P1002
首先这道题如果用搜索,每个节点两种状态,需要用dfs递归很多层。因此看看能不能用动态规划去优化重复子问题。

动态规划,每个位置只能从上面或右面走到,对应两个状态转移:
d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d p [ i ] [ j − 1 ] dp[i][j]=dp[i-1][j]+dp[i][j-1] dp[i][j]=dp[i1][j]+dp[i][j1]
另外要注意,马对应上面的位置下标有可能越界,为了方便起见,我们将所有的坐标对应的+2

#include<bits/stdc++.h> using namespace std;
long long int dp[40][40], ma[40][40];
int n, m, a, b;
int main() {cin >> n >> m >> a >> b;n += 2, m += 2, a += 2, b += 2;ma[a][b] = 1;ma[a - 1][b + 2] = 1;ma[a - 1][b - 2] = 1;ma[a + 1][b - 2] = 1;ma[a + 1][b + 2] = 1;ma[a + 2][b - 1] = 1;ma[a + 2][b + 1] = 1;ma[a - 2][b - 1] = 1;ma[a - 2][b + 1] = 1;dp[1][2] = 1;for (int i = 2; i <= n; i++) {for (int j = 2; j <= m; j++) {if (ma[i][j] == 1) {continue;}else dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}cout << dp[n][m];return 0;
}

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

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

相关文章

jenkins部署job

apt install fontconfig openjdk-11-jre wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.429/jenkins.wardeb包安装 wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/debian-stable/jenkins_2.414.3_all.debdpkg -i jenkins_2.414.3_all.deb 访问 http://…

阿里微服务质量保障系列:故障演练

对于很多大型企业(如阿里巴巴)来说,经过多年的技术演进,系统工具和架构已经高度垂直化,服务器规模也达到了比较大的体量。当服务规模大于一定量(如10000台)时,小概率的硬件故障每天都会发生。这时如果需要人的干预,系统就无法可靠的伸缩。 为此每一层的系统都会面向失…

用Rust和Scraper库编写图像爬虫的建议

本文提供一些有关如何使用Rust和Scraper库编写图像爬虫的一般建议&#xff1a; 1、首先&#xff0c;你需要安装Rust和Scraper库。你可以通过Rustup或Cargo来安装Rust&#xff0c;然后使用Cargo来安装Scraper库。 2、然后&#xff0c;你可以使用Scraper库的Crawler类来创建一个…

Linux系统下一些配置建议整理

1. 【推荐】高并发服务器建议调小 TCP 协议的 time_wait 超时时间。 说明&#xff1a;操作系统默认 240 秒后&#xff0c;才会关闭处于 time_wait 状态的连接&#xff0c;在高并发访问下&#xff0c;服 务器端会因为处于 time_wait 的连接数太多&#xff0c;可能无法建立新的…

轻量封装WebGPU渲染系统示例<19>- 使用GPU Compute材质多pass元胞自动机(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/GameOfLifeMultiMaterialPass.ts 系统特性: 1. 用户态与系统态隔离。 细节请见&#xff1a;引擎系统设计思路 - 用户态与系统态隔离-CSDN博客 2. 高频调用与低频调…

【Head First 设计模式】-- 观察者模式

背景 客户有一个WeatherData对象&#xff0c;负责追踪温度、湿度和气压等数据。现在客户给我们提了个需求&#xff0c;让我们利用WeatherData对象取得数据&#xff0c;并更新三个布告板&#xff1a;目前状况、气象统计和天气预报。 WeatherData对象提供了4个接口&#xff1a; …

Unity地面交互效果——4、制作地面凹陷轨迹

大家好&#xff0c;我是阿赵。   上一篇介绍了曲面细分着色器的基本用法和思路&#xff0c;这一篇在曲面细分的基础上&#xff0c;制作地面凹陷的轨迹效果。 一、思路分析 这次需要达到的效果是这样的&#xff1a; 从效果上看&#xff0c;这个凹陷在地面下的轨迹&#xff0…

平面扫描(Plane-sweeping)深度体会

先看文章 三维重建之平面扫描算法&#xff08;Plane-sweeping&#xff09;_plane sweeping_小玄玄的博客-CSDN博客 Plane Sweeping | 平面扫描 - 知乎 (zhihu.com) 注意平面Dm,这是其中一个平面&#xff0c;平面上有一个M点&#xff0c;这个点也再物体上。所以会被摄像机看到…

C++多态基础

文章目录 1.多态概念2.多态使用3.多态析构4.多态隐藏5.多态原理5.1.单类继承5.1.1.问题一&#xff1a;非指针或引用无法调用多态5.1.2.问题二&#xff1a;同类对象共用虚表5.1.3.问题三&#xff1a;子类对象拷贝父类对象虚表5.1.4.问题四&#xff1a;打印虚表地址和虚表内容 5.…

Linux文件系统的功能规划

对于运行的进程来说&#xff0c;内存就像一个纸箱子&#xff0c;仅仅是一个暂存数据的地方&#xff0c;而且空间有限。如果我们想要进程结束之后&#xff0c;数据依然能够保存下来&#xff0c;就不能只保存在内存里&#xff0c;而是应该保存在外部存储中。就像图书馆这种地方&a…

centos7.9 postgresql 16.0 源码安装部署

postgresql 16.0 源码安装部署 环境准备 系统主机名IP地址centos7.9postgres192.168.200.56 软件准备 postgresql-16.0.tar.gz https://ftp.postgresql.org/pub/source/v16.0/postgresql-16.0.tar.gz依赖安装 yum -y install systemd-devel readline readline-devel zlib-devel…

Spring Cloud智慧工地源码,利用计算机技术、互联网、物联网、云计算、大数据等新一代信息技术开发,微服务架构

智慧工地系统充分利用计算机技术、互联网、物联网、云计算、大数据等新一代信息技术&#xff0c;以PC端&#xff0c;移动端&#xff0c;设备端三位一体的管控方式为企业现场工程管理提供了先进的技术手段。让劳务、设备、物料、安全、环境、能源、资料、计划、质量、视频监控等…