UVA之1121 - Subsequence

简介:

【题目】

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 

Many test cases will be given. 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 there isn't such a subsequence, print 0 on a line by itself.

Sample Input 

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

Sample Output 

2 
3

【分析】

本题最直接的思路是二重循环,枚举子序列的起点和终点。代码如下(输入数据已存入数组A[1]~A[n])。

 

int ans = n+1;
for(int i = 1; i <= n; i++)
  for(int j = i; j <= n; j++) {
    int sum = 0;
    for(int k = i; k <= j; k++) sum += A[k];
    if(sum >= S) ans = min(ans, j-i+1);
  }
printf("%d\n", ans == n+1 ? 0 : ans);

很可惜,上述程序的时间复杂度是O(n3)的,因此,当n达到100 000的规模后,程序将无能为力。有一个方法可以降低时间复杂度,即常见的前缀和技巧。令Bi=A1+A2++Ai,规定B0=0,则可以在O(1)时间内求出子序列的值:Ai+Ai+1+…+Aj=Bj-Bi-1。这样,时间复杂度降为O(n2),代码如下。

 

B[0] = 0;
for(int i = 1; i <= n; i++) B[i] = B[i-1] + A[i];
int ans = n+1;
  for(int i = 1; i <= n; i++)
    for(int j = i; j <= n; j++)
      if(B[j] - B[i-1] >= S) ans = min(ans, j-i+1);
printf("%d\n", ans == n+1 ? 0 : ans);

遗憾的是,本题的数据规模太大,O(n2)时间复杂度的算法也太慢。不难发现,只要同时枚举起点和终点,时间复杂度不可能比O(n2)更低,所以必须另谋他路。比如,是否可以不枚举终点,只枚举起点,或者不枚举起点,只枚举终点呢?

我们首先试试只枚举终点。对于终点j,我们的目标是要找到一个让Bj-Bi-1≥S,且i尽量大(i越大,序列长度j-i+1就越小)的i值,也就是找一个让Bi-1≤Bj-S最大的i。考虑图1-29所示的序列。


当j=5时,B5=12,因此目标是找一个Bi-1≤12-7=5的最大i。注意到B是递增的(别忘了,本题中所有Ai均为整数),所以可以用二分查找。


【代码】

/*********************************
*   日期:2014-5-14
*   作者:SJF0115
*   题号: 1121 - Subsequence
*   地址:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=246&page=show_problem&problem=3562
*   来源:UVA
*   结果:Accepted
**********************************/
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;

#define N 100001

int A[N];
int B[N];

//二分查找最接近target但不大于target
int BinarySerach(int target,int R){
    int L = 0;
    int mid = 0;
    while(L < R){
        mid = L + (R - L) / 2;
        if(B[mid] > target){
            R = mid;
        }
        else{
            L = mid + 1;
        }
    }
    return L;
}

int main(){
    int n,s,i,j;
    //freopen("C:\\Users\\wt\\Desktop\\acm.txt","r",stdin);
    while(scanf("%d %d",&n,&s) != EOF){
        int minLen = n+1;
        B[0] = 0;
        for(i = 1;i <= n;i++){
            scanf("%d",&A[i]);
            //序列前缀和
            B[i] = B[i-1] + A[i];
        }
        for(j = 1;j <= n;j++){
            int target = B[j] - s;
            //二分查找
            int index = BinarySerach(target,j-1);
            if(index > 0){
                minLen = min(minLen,j-index+1);
            }
        }
        //没有满足条件的序列
        if(minLen == n+1){
            minLen = 0;
        }
        cout<<minLen<<endl;
    }//while
    return 0;
}


【相似题目】

编程之美之2.14 求数组的子数组之和的最大值


目录
相关文章
|
7月前
|
存储 NoSQL 关系型数据库
Apifox与Apipost数据库连接功能详细对比,让接口管理更高效!
Apipost 更加全面:无论是关系型还是非关系型数据库,它都为开发者提供了一站式解决方案,非常适合数据库架构复杂的大型项目。相对来说,Apifox偏重关系型分析和管理:若项目主要需求在于管理关系型数据库,而对非关系型的依赖较小,Apifox倒是可以应付。
182 2
|
缓存 应用服务中间件 Apache
缓存代理服务器的实现机制和技术选型
缓存代理服务器是一种特殊的代理服务器,其主要功能是缓存从目标服务器(通常是Web服务器)获取的数据,并在客户端再次请求相同数据时直接提供缓存的数据。通过缓存代理服务器可以加快访问速度并减轻目标服务器的负载。
527 110
|
搜索推荐 安全 数据安全/隐私保护
智能家居技术的未来趋势与挑战
【7月更文挑战第14天】随着物联网和人工智能技术的飞速发展,智能家居系统正逐步成为现代生活的新宠。本文将探讨智能家居技术的最新发展趋势,包括增强的用户体验、无缝的设备集成以及通过大数据分析实现的个性化服务。同时,文章还将讨论在实现这一愿景过程中面临的主要挑战,如数据安全、隐私保护、设备兼容性和用户接受度等问题。
246 2
|
云安全 监控 安全
企业对网络威胁情报计划的投资正在蓄势待发
企业对网络威胁情报计划的投资正在蓄势待发
|
运维 监控 Kubernetes
阿里云可观测峰会-行业实践分论坛| 学习笔记(一)
快速学习阿里云可观测峰会-行业实践分论坛
阿里云可观测峰会-行业实践分论坛| 学习笔记(一)
Verilog代码的风格规范
原则: 注释是对代码的“提示”,而不是文档。程序中的注释不可喧宾夺主,注释太多会让人眼花缭乱。 边写代码边注释,修改代码的同时要修改相应的注释,以保证注释与代码的一致性,不再有用的注释要删除。 如果代码本来就是清楚的,则不必加注释。
269 0
|
数据采集 Web App开发 JSON
Python 懂车帝口碑分爬虫
Python 懂车帝口碑分爬虫
|
存储 安全 架构师
Java 程序员必须掌握的 5 个注解!
划重点 自 JDK5 推出以来,注解已成为Java生态系统不可缺少的一部分。虽然开发者为Java框架(例如Spring的@Autowired)开发了无数的自定义注解,但编译器认可的一些注解非常重要。
166 0
Java 程序员必须掌握的 5 个注解!
|
Kubernetes 关系型数据库 MySQL