码迷,mamicode.com
首页 > 其他好文 > 详细

编程题-最短序列和(Subsequence)-尺取法

时间:2015-02-13 16:39:24      阅读:235      评论:0      收藏:0      [点我收藏+]

标签:编程   尺取法   最短序列和   

题目:

给定长度为n的整数数列 a0,a1,...,an?1以及整数S,求出总和不小于S的连续自序列的长度最小值。如果不存在,则输出0

样例:

输入
n = 10
S = 15
a = {5 , 1,3 ,5 ,10,7,4,9,2,8}
输出
2 (5 ,10)

思路:

尺取法通常的是保留数组的一对下标(开始到结束),然后根据实际情况交替移动。

我们假设从i开始总和超过S的连续子序列如果为ai,ai+1...ai+j

ai+ai+1+...+ai+jS

并且
ai+ai+1+...+ai+j?1<S

当我们找出这样的子序列以后,再从序列开始的地方减去ai,如果和依然大于等于S,则继续从序列开始的地方减去第一个,直到小于S,那么便得出一个解,当所有解求出来以后,找出最小的解便是该问题的解。

画图说明一下可能更形象,以样例输入为例子:
1.初始化的时候,开始指针和结束指针都指向第一个,此时的子序列和为S=ai<15

技术分享
2. 向右移动结束指针,当移到10位置,第一次出现S=a0+a1+a2+a3+a415
技术分享
3.这时移动开始的指针,先向右移动一格S=a1+a2+a3+a415
技术分享
4.继续移动开始的指针,当移动到10的时候,S=a4<15,这时就得到一个解(a3,a4)
技术分享
5,然后不断重复上面的步骤,找出最短的一个就是该问题的解

代码

#include <iostream>
using namespace std;

int main(){
    int n,S;
    cout<<"n = ";
    cin>>n;
    cout<<"S = ";
    cin>>S;
    int *a = new int[n];
    cout<<"input a[] :";
    for(int i=0;i<n;i++){
        cin>>a[i];
    }

    int b=0,e=0,sum=0,res=n+1;
    while(1){
        //移动结束的下标
        while(e < n && sum < S){
            sum+=a[e++];
        }
        if(sum < S) break;
        //移动开始的下标
        while(sum >= S){
            sum-=a[b++];
        }

        res=min(res,e-b+1);
    }
    if(res>n){
        res=0;
    }
    cout<<res<<endl;
}

运行结果

n = 5
S = 11
input a[] :1 2 3 4 5
3

编程题-最短序列和(Subsequence)-尺取法

标签:编程   尺取法   最短序列和   

原文地址:http://blog.csdn.net/lizo_is_me/article/details/43794745

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!