poj 3061 Subsequence

news/2024/11/19 1:26:54/文章来源:https://www.cnblogs.com/pangyou3s/p/18198823

题目链接:

来自罗勇军《算法竞赛》书中的习题。
题意:给长度为 \(N\) 的数组和一个整数 \(S\),求总和不小于 \(S\) 的连续子序列的最小长度。

方法一:尺取法

主要思想为:当 \(a_1, a_2 , a_3\) 满足和 \(\geqslant S\),得到一个区间长度 \(3\), 那么去掉开头 \(a_1\),剩下 \(a_2,a_3\), 是否满足 \(\geqslant S\),如果满足,那么区间长度更新,如果不满足,那么尾部向后拓展,判断 \(a_2,a_3,a_4\) 是否满足条件。重复这样的操作。

主要分为四步:

  1. 如果 \(\rm sum<S\),就不断的放大 \(\rm right\),直到 \(\rm sum \geqslant S\) 或者 \(\rm right>N\)
  2. 如果第 \(1\) 步循环结束,\(sum<S\),程序结束,不走到 \(3\)
  3. 满足 \(\rm sum \geqslant S\),更新 \(\rm res=min(res,right-left)\)
  4. 放大 \(\rm left\) 回到 \(1\)

时间复杂度为 \(O(n)\).

\(\rm eg.\)
image

\(\rm ans=2\).

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;int s[100005];void solve() {int N, S;cin >> N >> S;for (int i = 1; i <= N; i++) {cin >> s[i];}int l = 1, r = 1, sum = 0, ans = N + 1;while (l <= r) {while (r <= N && sum < S) sum += s[r++];if (sum < S) break;ans = min(ans, r - l);sum -= s[l++];}if (ans == N + 1) cout << 0 << "\n";else cout << ans << "\n";
}int main()
{int t = 1;cin >> t;while (t--) solve();return 0;
}

方法二、前缀和+二分

如果想要求出序列中某个连续子序列的和,我们可以采用前缀和的方式求出。得到前缀和之后,我们可以采取双循环枚举的方式枚举序列的所有子区间,从而得出合适的区间长度。但由于本题数据范围为 \(O(10^5)\),显然这样会超时。

for(int i = 1; i <= n; i ++) {for(int j = i; j <= n; j ++ ){if(sum[j] - sum[i - 1] >= s) {ans = min(ans,j - i + 1);break;} }
}

分析第二重循环可以发现,我们只需要找到第一个满足 \(\rm sum[j] - sum[i - 1] \geqslant s\) 的就可以直接 \(\rm break\) 了,但是我们需要去枚举每一个 \(\rm sum[j]\),比较浪费时间,可以发现, \(\rm sum[x]\) 是一个递增的序列,这时候我们就可以采取二分的策略,寻找到第一个满足 \(\rm sum[j] - sum[i - 1] \geqslant s\)\(j\)。时间复杂度为 \(O(nlogn)\).

#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>#define INF 0x3f3f3f3fusing namespace std;const int maxn = 1e5 + 10;typedef long long LL;LL sum[maxn], a[maxn];int t, n, s; int main() {cin >> t;while(t --) {memset(sum,0,sizeof(sum));cin >> n >> s;for(int i = 1; i <= n; i ++) {cin >> a[i];// 前缀和 sum[i] = sum[i - 1] + a[i];}// 特判,如果整个序列和 < s,则一定没有合适的区间 if(sum[n] < s) puts("0");else {int ans = INF;for(int i = 1; i <= n; i ++) {int l = i;// 后面的判断没有意义,可以直接跳出循环 if(sum[n] - sum[l - 1] < s) break;int r = n;// 二分查找最小的右端点满足 sum[mid] - sum[i - 1] >= s while(l < r) {int mid = l + r >> 1;if(sum[mid] - sum[i - 1] < s) l = mid + 1;else r = mid;}// 寻找到最小的区间 ans = min(ans,r - i + 1);}cout << ans<< endl;}}return 0;
}

参考文献:poj3061:Subsequence(最短子序列和) -- 前缀和与二分

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

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

相关文章

汇编语言基础及编译原理(网安)

汇编语言基础及编译原理 二进制基础 程序的编译 汇编与链接从c语言到可执行程序 源代码.c 编译 汇编代码.s 汇编 目标文件.o 链接(静态库直接拷贝,动态库运行时通过动态链接方式加载) 可执行文件(p)x86机器指令入门 栈 一种先进后出的数据结构 被用于保存函数的局部(保存…

SkyWalking 单机安装 + 集成springboot

一、下载地址 https://skywalking.apache.org/downloads/ 需下载安装包:SkyWalking APM (v9.6.0) (新版本 Booster UI 已集成在 SkyWalking APM中)apache-skywalking-apm-9.6.0.tarJava Agent (v9.1.0)apache-skywalking-java-agent-9.1.0.tar二、安装 2.1、安装SkyWalking …

R语言中小数点如何实现进位

001、round,四舍五入> a <- 5.345 ## 舍去 > round(a) [1] 5 > b <- 5.824 ## 进位 > round(b) [1] 6 002、round,四舍五入指定小数位数> a <- 8.426532 > round(a, 1) ## 保留一位小数,四舍五入 [1] 8.4 > round…

C122 李超树合并+DP CF932F Escape Through Leaf

视频链接:C122 李超树合并+DP CF932F Escape Through Leaf_哔哩哔哩_bilibili C65【模板】线段树合并 P4556 [Vani有约会]雨天的尾巴 - 董晓 - 博客园 (cnblogs.com) CF932F Escape Through Leaf#include <iostream> #include <cstring> #include <algorith…

kettle从入门到精通 第六十一课 ETL之kettle 任务调度器,轻松使用xxl-job调用kettle中的job和trans

1、大家都知道kettle设计的job流程文件有个缺点:只能设置简单的定时任务,无法设置复杂的如支持cron表达式的job。 今天给大家分享一个使用xxl-job调度carte的流程文件的示例。整个调度流程图如下: 1)xxl-job-admin,页面可视化配置任务。 2)xxl-job-executor,job执行器,…

PKUSC 2024 最短路径

本文首发于 [QOJ](https://qoj.ac/blog/skip2004/blog/866) 大家好,我是钱哥,我来写一下 PKUSC2024 最短路径 的题解。没有做过这个题的同学可以先自行做一做。 我们下面来讲解一下如何一步步解决这个题目。 subtask 4 首先,我们来解决第一个具有挑战性的子任务:\(m \leq…

工业福利!用.NET快速开发物联网扫码器设备的通用扫码功能

不管你是用.net framework还是用.net core或者更高版本.net环境,这篇文章也许都能帮到你!因为接下来我会提供一个简单粗暴的方式,来快速实现多款扫码器的通用扫码功能。目前本地测试过的包括基恩士系列、康耐视系列、以及其他支持以太网通信的多款小众厂家等。 下面开始重点…

执行npm run serve有时提示npm update check failed

背景:这个错误虽说无关紧要,但有时候会出现就感觉不爽。 错误提示: 解决方法:在网络上查阅资料后才知道是因为文件夹权限的问题 (1.)删除目录configstore由于权限问题,该目录经常出现故障。如果删除该目录,则下次运行命令时将重新生成该目录。 (2.)在 Windows 上删除…

IKNP协议详解

详细介绍OT extension的重要文章: Extending Oblivious Transfers Efficiently. 作者是Yuval Ishai, Joe Kilian, Kobbi Nissim, and Erez Petrank, 发表在2003的Crypto上.一起学习OT extension的重要文章: Extending Oblivious Transfers Efficiently. 作者是Yuval Ishai, Joe…

vulnhub - w1r3s.v1.0.1

对于vulnhub靶机w1r3s.v1.0.1的渗透流程vulnhub - w1r3s.v1.0.1 高质量视频教程 - b站红队笔记 靶机下载 本地环境 本机ip:192.168.157.131 w1r3s虚拟机设置NAT模式 信息收集 扫描网段得到攻击机ip:192.168.157.158详细信息扫描 nmap -A -p- 192.168.157.158开放了四个端口 2…

自研WPF插件系统(沙箱运行及热插拔)

前言插件化的需求主要源于对软件架构灵活性的追求,特别是在开发大型、复杂或需要不断更新的软件系统时,插件化可以提高软件系统的可扩展性、可定制性、隔离性、安全性、可维护性、模块化、易于升级和更新以及支持第三方开发等方面的能力,从而满足不断变化的业务需求和技术挑…

通过CM 1542-1与1500CPU进行S7通信

通过CM 1542-1与1500CPU进行S7通信时,通信伙伴的SIMATIC-ACC不要勾选,设置正确的机架/插槽,TSAP设置为03.01才能通信成功。如果通过1500CPU本体网口与1500CPU进行S7通信时,仅需勾选SIMATIC-ACC就可以通信成功