Description:

给定长度为n的整数数列,A[0],A[1],A[2]….A[n-1]以及整数S,求出总和不小于S的连续子序列的长度的最小值。如果解不存在,则输出0。

Input:

输入数据有多组,每组数据第一行输入n,S, (10<n<10^5,S<10^8)第二行输入A[0],A[1],A[2]….A[n-1] ( 0<A[i]≤10000),处理到文件结束。所有输入数据都在int范围之内。

Output:

每组数据输出结果占一行。

Sample Input:

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

Sample Output:

2

>>>>>>>>>这题有一个技巧,叫做尺缩法
-----------------------------------------------------------------------------------------------------------------------

(1)   设置两个指针s和t,一开始都指向数列第一个元素,此外sum=0,res=0;

(2)   只要sum<S,就将sum增加一个元素,t加1;

(3)   直到sum>=S,更新res=min(res,t-s);

(4)   将sum减去一个元素,s加1,执行(2)。

上述流程反复地推进区间的开头和末尾,来求取满足条件的最小区间。

----------------------------------------------------------------------------------------------------------------------------------------------------------

#include<iostream>
using namespace std;
int min(int a,int b){if(a>b)return b;return a;}
int main(){
int n,S,A[];
int i,j,k;
while(cin>>n>>S){
//输入数据部分
for(int i=;i<n;i++)cin>>A[i];
//尺缩法计算部分
int res=n+,s=,t=,sum=;
for(;;){
while(t<n && sum<S)sum+=A[t++];
if(sum<S)break;
res=min(res,t-s);
sum-=A[s++];
}
if(res>n)res=;
//输出结果
cout<<res<<'\n';
}
return ;
}

>>>>>>>>> 同样也可以用用lower_bound:

--------------------------------------------------------------------------------------------------------------------------------------------------------

lower_bound(ForwardIterator first,ForwardIterator last, const Type &value,Compare comp );

 lower_bound()返回一个 iterator 它指向在[first,last)标记的有序序列中可以插入value,而不会破坏容器顺序的第一个位置,而这个位置标记了一个大于等于value 的值。

例如,有如下序列:

   ia[]={12,15,17,19,20,22,23,26,29,35,40,51};
   用值21调用lower_bound(),返回一个指向22的iterator。用值22调用lower_bound(),也返回一个指向22的iterator。根据comp进行排序和比较。
 注意:::调用lower_bound之前必须确定序列为有序序列,否则调用出错。函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于    val的第一个元素位置。如果所有元素都小于val,则返回last的位置。
   --------------------------------------------------------------------------------------------------------------------------------------------------------
   所以这里我们可以这样处理:

我们可以计算出sum(i)=a0+a1+...+ai。那么sum(t)-sum(s)=as+a(s+1)+...a(t-1)。这样我们可以实现先求出一个sum(n)。sum(n)-sum(i)=s。我们只需要去筛选sum(i)。这样可以用二分搜索的方法快速求出最小的长度。

int t=lower_bound(sum+i,sum+n,sum[i]+s)-sum;求出来的是从ai到at(i<=t<=n)和比s小的最小值的下标。

 #include<algorithm>
using namespace std;
int min(int a,int b){if(a>b)return b;return a;}
int n,s;
int a[];
int sum[];
int main(){
while(cin>>n>>s){
//sum归0;
memset(sum,,sizeof(sum));
//输入并计算sum;
for(int i=;i<n;i++){
cin>>a[i];
sum[i+]=sum[i]+a[i];
}
//运算求解输出;
if(sum[n]<s){
cout<<""<<endl;
}
else{
int ret=n;
for(int i=;sum[i]+s<=sum[n];i++){
int t=lower_bound(sum+i,sum+n,sum[i]+s)-sum;
ret=min(ret,t-i);
}
cout<<ret<<endl;
}
}
return ;
}

>>>>>>>>附加:折半查找法:

 int lowerBound(int array[],int left,int right,int value)
{
int mid=,half=;
int len=(right+left+)/;
while(len>)
{
half=len>>; //数据长度折半
mid=left+half; //计算中点
if (array[mid]<value) //调整总长与起点
{
len=len-half-;
left=mid+;
}
else
len=half;
}
return left;
}

lower_bound版本一:

 int lowerBound(int array[],int left,int right,int value)
{
int mid=;
while(left<right)
{
mid=(right+left)/; //计算中点
if (array[mid]<value) //调整起点或者终点
left=mid+;
else
right=mid;
}
return right;
}

lower_bound版本二:

 int upperBound(int array[],int left,int right,int value)
{
int mid=,half=;
int len=(right+left+)/;
while(len>)
{
half=len>>; //长度折半
mid=left+half; //计算中点
if (array[mid]>value) //调整长度与起点
len=half;
else
{
len=len-half-;
left=mid+;
}
}
return left;
}

upper_bound版本一:

 int upperBound(int array[],int left,int right,int value)
{
int mid=;
while(left<right)
{
mid=(right+left)/; //计算中点
if (array[mid]>value) //调整起点或者终点
right=mid;
else
left=mid+;
}
return right;
}

upper_bound版本二:

 int binarySearch(int array[],int left,int right,int value)
{
int mid;
while(left<=right)
{
mid=(left&right)+((left^right)>>); //防止溢出
if(array[mid]==value)
return mid;
else if (array[mid]<value)
left=mid+;
else
right=mid-;
}
return -;
}

折半查找:

 

[ACM_其他] 总和不小于S的连续子序列的长度的最小值——尺缩法的更多相关文章

  1. lintcode-397-最长上升连续子序列

    397-最长上升连续子序列 给定一个整数数组(下标从 0 到 n-1, n 表示整个数组的规模),请找出该数组中的最长上升连续子序列.(最长上升连续子序列可以定义为从右到左或从左到右的序列.) 注意事 ...

  2. BNUOJ 4215 最长公共连续子序列

    最长公共连续子序列 Time Limit: 1000ms Memory Limit: 65536KB   64-bit integer IO format: %lld      Java class ...

  3. ACM-DP之最大连续子序列——hdu1231

    ***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...

  4. HDU 1231:最大连续子序列 解题报告

    第一次写博客, 自己总结写出了一道题感觉值得保存. 自己总结的规律:求最大连续子序列, 可以先求包括第N项在内的前N项最大值, (因为每一项都求过后, 前N项最大值最大的那一个元素所连续的序列即为最大 ...

  5. HDU 1231 最大连续子序列 &&HDU 1003Max Sum (区间dp问题)

    C - 最大连续子序列 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit ...

  6. HDU 1003 Max Sum && HDU 1231 最大连续子序列 (DP)

    Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  7. 最大连续子序列 -- hdu -- 1231

    http://acm.hdu.edu.cn/showproblem.php?pid=1231 最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  8. K:求取数组中最大连续子序列和的四个算法

    相关介绍:  求取数组中最大连续子序列和问题,是一个较为"古老"的一个问题.该问题的描述为,给定一个整型数组(当然浮点型也是可以的啦),求取其下标连续的子序列,且其和为该数组的所有 ...

  9. 寻找最大连续子序列/Find the max contiguous subsequence

    寻找最大连续子序列 给定一个实数序列X1,X2,...Xn(不需要是正数),寻找一个(连续的)子序列Xi,Xi+1,...Xj,使得其数值之和在所有的连续子序列数值之和中为最大. 一般称这个子序列为最 ...

随机推荐

  1. information_schema系列四(跟踪,列约束,表和列)

    这个系列的文章主要是为了能够让自己了解MySQL5.7的一些系统表,统一做一下备注和使用,也希望分享出来让大家能够有一点点的受益. 1:KEY_COLUMN_USAGE 按照官方的解释,这个表描述的是 ...

  2. 数据库中int类型存在空数据开发过程中model和dal层处理方法

    model层 public Int32? IsFullAttendance { get; set; } dal层  if (dr["IsFullAttendance"] + &qu ...

  3. localstorage,sessionstorage使用

    今天看了一下HTML5,也算是简单的学习一下吧,HTML5 提供了两种在客户端存储数据的新方法:localstorage,sessionstorage. localStorage - 没有时间限制的数 ...

  4. [转]Debug 和 Release 编译方式的区别

    本文主要包含如下内容: 1. Debug 和 Release 编译方式的本质区别 2. 哪些情况下 Release 版会出错 3. 怎样“调试” Release 版的程序 Debug 和 Releas ...

  5. scala 学习: 逆变和协变

    scala 逆变和协变的概念网上有很多解释, 总结一句话就是 参数是逆变的或者不变的,返回值是协变的或者不变的. 但是为什么是这样的? 协变: 当s 是A的子类, 那么func(s) 是func(A) ...

  6. 解决IE上登陆oracle OEM时报:“证书错误,导航已阻止”的错误

    今天在IE上登陆OEM时,报证书错误,导航已阻止,我选择:继续浏览此网站(不推荐),但是点了之后还没有反应,在网上搜了很多,原因基本都是windows的问题,最后发现问题是:oracle oem证书的 ...

  7. DrawingControl控件在Add Page时报故障的问题

    Visio二次开发用到了Drawing Control控件.在控件上添加新页面时,visual编译器报内存保护故障“尝试读取或写入受保护的内存.这通常指示其他内存已损坏.”,这个问题困扰了我很久,最后 ...

  8. MVC学习地址

    http://www.cnblogs.com/n-pei/tag/Asp.net%20MVC/

  9. MySQL Batch 与 Transaction

    最近在数据库上经常遇到死锁问题. 表现的问题有 1. 有一个查询为: 1) 一个复杂的 select 查处一组大数据 2) 使用事务 update 这组数据的状态 为了让锁定的时间变短, 我将这整个大 ...

  10. 揭开HTTP网络协议神秘面纱系列(三)

    HTTP首部字段有四种类型:通用首部字段,请求首部字段,响应首部字段,实体首部字段. 通用首部字段: 首部字段 说明 Cache-Control 控制缓存的行为 Connection 逐跳首部.连接的 ...