---恢复内容开始---

Subsequence
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 10487   Accepted: 4337

Description

A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 10000, and a positive integer S (S < 100 000 000) are given. Write a program to find the minimal length of the subsequence of consecutive elements of the sequence, the sum of which is greater than or equal to S.

Input

The first line is the number of test cases. For each test case the program has to read the numbers N and S, separated by an interval, from the first line. The numbers of the sequence are given in the second line of the test case, separated by intervals. The input will finish with the end of file.

Output

For each the case the program has to print the result on separate line of the output file.if no answer, print 0.

Sample Input

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

Sample Output

2
3

Source

 
题意:给你n个一连串的数字,求不小于m的最短的连续的数字长度;
分析:暴力的话复杂度n^2,肯定会超时,有两种方法,都要掌握,第一种是lower_bound函数的使用,lower_bound的复杂度是log(n)。所以该算法的复杂度是nlog(n),相比于暴力,算法的优化仅仅体现在使用了lower_bound将n变为了log(n).
#include<cstdio>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a) memset(a,0,sizeof(a))
typedef long long LL;
typedef unsigned long long ULL;
const int mod = 1000000007;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
long long mid,l,r,n,m;
int sum[100005];
int main()
{
int n,cas,s,k,ans,res;
cin>>cas;
while(cas--)
{
scanf("%d %d",&n,&s);
sum[0]=0;ans=100005;
for(int i=1;i<=n;i++)
{
scanf("%d",&sum[i]);
sum[i]+=sum[i-1];   //将数组求和是常用的技巧
}
if(sum[n]<s)
{
cout<<"0"<<endl;
continue;
}
for(k=0;sum[n]-sum[k]>=s;k++)  //枚举起点
{
res=lower_bound(sum+k,sum+n+1,sum[k]+s)-(sum+k);  //第一个大于等于该值的位                                          //置
if(res<ans)
ans=res;
}
printf("%d\n",ans);
}
return 0;
}

  下面重点介绍尺取法:

  尺取法的核心思想:假设当前a[s]+s[s+1]+...a[t]是最初>=sum的,那么当s变为s+1时,即a[s+1]+s[s+2]+...a[t+n]要想仍然成为最初>=sum的,则t+n>=t(a[s]可能为0),依据这一思想,可以设置两个”指针“,一个指向p一连续序列的开头位置,另一头q指向结尾位置,该子序列之和>=sum,则当p向右推移时,则q也应向右推移直到两指针之间的序列之和再次最初>=sum,复杂度是O(n),其实觉得尺取法最显著的优势就在于能够保存中间一部分子序列的计算结果,这也是其复杂度更低的原因。

#include<cstdio>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a) memset(a,0,sizeof(a))
typedef long long LL;
typedef unsigned long long ULL;
const int mod = 1000000007;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
long long mid,l,r,n,m;
int a[100005];
int main()
{
int n,cas,s;
cin>>cas;
while(cas--)
{
scanf("%d %d",&n,&s);
a[0]=0;a[n+1]=0;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int p=0,q=0,v=0,ans=n+1;
while(v<s&&q<=n)
{
q++;
v+=a[q];
}
if(q==n+1)
{
cout<<"0"<<endl;
continue;
}
for(;;)
{
while(v<s&&q<=n)
{
q++;
v+=a[q];
}
if(q==n+1)
break;
if(ans>q-p)
ans=q-p;
p++;
v-=a[p];
}
printf("%d\n",ans);
}
return 0;

  

POJ 3061  Subsequence   尺取法   挑战146页的更多相关文章

  1. POJ 3061 Subsequence(尺取法)

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

  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 尺取法

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

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

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

  5. poj 3061 题解(尺取法|二分

    题意 $ T $ 组数据,每组数据给一个长度 $ N $ 的序列,要求一段连续的子序列的和大于 $ S $,问子序列最小长度为多少. 输入样例 2 10 15 5 1 3 5 10 7 4 9 2 8 ...

  6. POJ 3061 Subsequence 尺取

    Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14698   Accepted: 6205 Desc ...

  7. POJ 3061 Subsequence 二分或者尺取法

    http://poj.org/problem?id=3061 题目大意: 给定长度为n的整列整数a[0],a[1],--a[n-1],以及整数S,求出总和不小于S的连续子序列的长度的最小值. 思路: ...

  8. POJ 3061 Subsequence ( 尺取法)

    题目链接 Description A sequence of N positive integers (10 < N < 100 000), each of them less than ...

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

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

  10. POJ 3061 Subsequence【二分答案】||【尺取法】

    <题目链接> 题目大意: 给你一段长度为n的整数序列,并且给出一个整数S,问你这段序列中区间之和大于等于S的最短区间长度是多少. 解题分析:本题可以用二分答案做,先求出前缀和,然后枚举区间 ...

随机推荐

  1. (5.3)mysql高可用系列——mysql复制之复制的参数

    参考:https://www.iteye.com/blog/shift-alt-ctrl-2269539 详情 [1]参数 #[1.1]基本参数 bind-address=192.168.1.201 ...

  2. Ajax异步上传在SSM框架中的应用

    最近在做毕业设计,由于毕设中要实现图片上传和视频上传的功能.突然发现原来的Form表单中的file已经满足不了我了,于是在一番折腾之后终于让我找到了一个简便的上传方式.下面来和大家分享一下我的过程. ...

  3. NOIP2012 D2T3 疫情控制 题解

    题面 这道题由于问最大值最小,所以很容易想到二分,但怎么验证并且如何实现是这道题的难点: 首先我们考虑,对于一个军队,尽可能的往根节点走(但一定不到)是最优的: 判断一个军队最远走到哪可以树上倍增来实 ...

  4. 第一次编译ffmpeg

    今天开始玩ffmpeg了. 从官网下载来的压缩包,不会编译诶,于是我开始研究起来了. 下面就是实时记录的随笔: 首先是从官网下载来的ffmpeg,就是下面这个版本,目前的最新版吧. http://ff ...

  5. Eureka注册中心

    Eureka简介 Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的.SpringClou ...

  6. java 如何编写多线程的代码

    线程是干活的所以线程一定是Thread,或者改线程实现Runnable接口多线程是竞争关系,所以多个线程竞争同一个资源,也就是同一个对象所以这个竞争对象发到Thread中即: // resources ...

  7. jenkins-docker部署

    安装docker http://www.cnblogs.com/cjsblogs/p/8717304.html 安装jenkins mkdir -p /root/dockerfile/base/cen ...

  8. 牛客 545A 小A与最大子段和 & CF 660F Bear and Bowling 4

    大意: 给定序列$a$, 求选择一个子区间$[l,r]$, 使得$\sum\limits_{i=l}^r(i-l+1)a_i$最大. $n\le2e5, |a_i|\le 1e7$. 记$s[i]=\ ...

  9. opencv中的高维矩阵Mat

    本示例程序主要是通过实例演示高维Mat的寻址方式. //3,4分别表示行数.列数,所以3*4是一个页面的元素数,2表示有2个3*4 ,b=,c=; int size[]={a,b,c}; float* ...

  10. springcloud(十一)-Zuul聚合微服务

    前言 我们接着上一节.在许多场景下,外部请求需要查询Zuul后端的多个微服务.比如一个电影售票手机APP,在购票订单页上,既需要查询“电影微服务”获得电影相关信息,又需要查询“用户微服务”获得当前用户 ...