题意

$ T $ 组数据,每组数据给一个长度 $ N $ 的序列,要求一段连续的子序列的和大于 $ S $,问子序列最小长度为多少。

输入样例

2
10 15
5 1 3 5 10 7 4 9 2 8
5 11
1 2 3 4 5

输出样例

2
3

解析

我们很容易发现对于这题我们可以二分答案,先找出一个初始长度,判断是否存在合法序列,如果存在缩小长度,如果不存在加长长度。

时间复杂度 $ O(nlogn) $

代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int T,n,m,k,sum[100010];
bool cheak(int x){
int l,r;
for(int i=1;i+x-1<=n;++i){
l=i;r=i+x-1;
if(sum[r]-sum[l-1]>=m) return true;
}
return false;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%d",&k);
sum[i]=sum[i-1]+k;
}
int l=1,r=n,ans=0;
while(l<=r){
int mid=(l+r)>>1;
if(cheak(mid)){ans=mid;r=mid-1;}
else l=mid+1;
}
printf("%d\n",ans);
}
return 0;
}

对于这一题我们还有一种其它的做法,尺取法。

1.先固定左端点 $ l=1 $,右端点一直向右走,直到满足总和 $ data>=S $ 。

2.我们可以尝试删去左端点即 $ l $ 向右移动,如果发现任然满足 $ data>=S $ 更行答案,不满足右端点向右走。

3.当右端点到达 $ N $ 时不再移动右端点,一直移动左端点直到不满足 $ data>=S $ 就 $ break $。

对于其正确性这里不做证明(我菜爆了不会

可以保证的是这种做法会扫过所以可能出现答案的区间。

时间复杂度 $ O(n) $

代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int T,n,m,ans,a[100010];
int main(){
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
}
int data=0,l=1,r=1;ans=1<<30;
while(true){
while(data<m&&r<=n) data+=a[r++];
if(data<m) break;
ans=min(ans,r-l);
data-=a[l++];
}
if(ans==1<<30) printf("0\n");
else printf("%d\n",ans);
}
return 0;
}

值得一提的是,在poj上两种方法的时间相差不大,有可能是数据太小了吧。

poj 3061 题解(尺取法|二分的更多相关文章

  1. POJ 3061 Subsequence 尺取法

    转自博客:http://blog.chinaunix.net/uid-24922718-id-4848418.html 尺取法就是两个指针表示区间[l,r]的开始与结束 然后根据题目来将端点移动,是一 ...

  2. POJ 3061 Subsequence 尺取法 POJ 3320 Jessica's Reading Problem map+set+尺取法

    Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13955   Accepted: 5896 Desc ...

  3. POJ 3061 Subsequence(尺取法)

    Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18145   Accepted: 7751 Desc ...

  4. POJ 3061 Subsequence 尺取法,一个屌屌的O(n)算法

    Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9050   Accepted: 3604 Descr ...

  5. 题解报告:poj 3061 Subsequence(前缀+二分or尺取法)

    Description A sequence of N positive integers (10 < N < 100 000), each of them less than or eq ...

  6. POJ——3061Subsequence(尺取法或二分查找)

    Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11224   Accepted: 4660 Desc ...

  7. Subsequence---poj3061(尺取法||二分)

    题目链接:http://poj.org/problem?id=3061 题意:给n个正整数和一个数S,求出总和不小于S的连续子序列的长度的最小值,如果无解输出0: 我们可以用sum[i]表示前i项的和 ...

  8. BestCoder Round #86 二,三题题解(尺取法)

    第一题太水,跳过了. NanoApe Loves Sequence题目描述:退役狗 NanoApe 滚回去学文化课啦! 在数学课上,NanoApe 心痒痒又玩起了数列.他在纸上随便写了一个长度为 nn ...

  9. POJ:3061-Subsequence(尺取法模板详解)

    Subsequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 18795 Accepted: 8043 Descript ...

随机推荐

  1. [内网渗透]Mimikatz使用大全

    0x00 简介 Mimikatz 是一款功能强大的轻量级调试神器,通过它你可以提升进程权限注入进程读取进程内存,当然他最大的亮点就是他可以直接从 lsass.exe 进程中获取当前登录系统用户名的密码 ...

  2. RIP子网划分及扩展详解

  3. Perl寻路A*算法实现

    A*算法:A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法.估价值与实际值越接近,估价函数取得就越好. 公式表示为: f(n)=g(n)+h(n),其中 f(n) 是从初始点经 ...

  4. 【Java.Regex】用正则表达式查找Java源文件中的注释

    代码: package regex; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.I ...

  5. ISO/IEC 9899:2011 条款6.8.1——标签语句

    6.8.1 标签语句 语法 1.labeled-statement: identifier    :    statement default    :    statement case    co ...

  6. spring2.5 jdk1.8

    今天运行一个14年基于spring2.5的项目,出现下面错误 Unexpected exception parsing XML document from class path resource .. ...

  7. jsoup获取文章内容

    jsoup爬取文章内容 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Se ...

  8. netty5服务端检测心跳超时断连

    客户端每5秒发送一次心跳给服务端,服务端记录最后一次心跳时间,通过定时任务每10秒检测一下,如果当前时间与最后一次收到的心跳时间之差超过某个阈值,断开与客户端的连接.基于之前的例子(netty5心跳与 ...

  9. source insight 使用配置(私人)

    1.输入两个空格,两个空格全消失,前后的字粘在一起显示,不想这样,就取消下图的勾.

  10. 头文件里声明和定义,Qt编译不过问题

    1.现象1 Qt5.2.1,新建头文件,声明一个类,然后在此头文件中实现类的static变量和方法,但是编译不过,显示:multiple definition of `xxx'. 2.现象2 在高版本 ...