尺取法

来源:互联网 发布:淘宝模特 编辑:程序博客网 时间:2024/04/29 08:20

尺取法;应用于有这么一类问题,需要在给的一组数据中找到不大于某一个上限的“最优连续子序列
先拿poj3061;http://poj.org/problem?id=3061
给长度为n的数组和一个整数m,求总和不小于m的连续子序列的最小长度;
这里就适合用,尺取法;;
先看一下他查找的思路吧’
这里写图片描述
正如该图,黄色区域就是每次查找的范围,依次可以大概看出尺取法的查找过程;
可以看题目代码了;

#include<stdio.h>int main(){    int t,n,s,ans, min, i, l,w,a[100005];    scanf("%d",&t);    while(t--){        scanf("%d %d",&n,&s);        for(i = 0; i < n; i++){            scanf("%d",&a[i]);        }        int l = 0,w= 0,sum = 0,ans=n+1;        while(1){            while(w < n && sum<s){                sum+=a[w];                w++;            }            if(sum < s){                break;              }            min = w-l;            if(min > ans)                min = ans;            ans = min;            sum -= a[l++];        }        if(ans == n+1){            printf("0\n");        }        else{            printf("%d\n",ans);        }    }

上面是剪切复制来的,下面的连接有原文

下面是用我用递归函数写的,youcuo,xianzhneglizhe,denglaoshibangman

#include<stdio.h>int main(){    int Rulerextraction(int a[],int i,int p,int sum,int min);    int i=0,p=0,sum=0,min=10;    int a[10]={5,1,3,5,10,7,4,9,2,8};    min=Rulerextraction(a,i,p,sum,min);    printf("最小区间:%d",min);    return 0;}int Rulerextraction(int a[],int i,int p,int sum,int min){    while(sum<=14&&i<10)    //前面向前爬动        sum=+a[i++];    while(1)               //后面的向前爬动,这里的死循环用的非常巧妙 {                        //本身开始不满足循环条件,死循环加break函数,很好        sum=-a[p++];        if(sum<=14)            break;    }    min=(min<(i-p+1)?min:(i-p+1));//只有在小于14的时候才跳出循环,上一个才刚好大于14    if(i<10)        Rulerextraction(a,i,p,sum,min);    else        return(min);}
这里我最想说的是,递归函数与死循环能否相互转换的关系

一、他们都可以看成循环

二、递归函数的终止条件可以由while(1)+break代替

尺取法视频介绍

尺取法题目及答案出

原创粉丝点击