尺取法 poj3061 poj3320

来源:互联网 发布:淘宝店铺收藏链接转换 编辑:程序博客网 时间:2024/05/16 00:25

http://poj.org/problem?id=3061

/*(1).s=t=sum=0初始化(2).只要sum<S,sum+=a[t],然后t++(3).如果(2)中无法sum>=S则无解。有解则res=min(res,t-s);(4).sum减去序列头s,s=s+1,重复(2)*/#include<algorithm>#include<cstdio>using namespace std;typedef long long LL;const int MAX = 100005;int N,S,a[MAX];void solve(){    int res = N+1;    int s=0,t=0,sum=0;    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=0;///无解    printf("%d\n",res);}int main(){    int T;    scanf("%d",&T);    while(T--){        scanf("%d%d",&N,&S);        for(int i=0;i<N;i++)scanf("%d",&a[i]);        solve();    }    return 0;}




http://poj.org/problem?id=3320


/*第i页有知识点a[i],求学完所有的知识点的最少连续页数假设从某一页s开始阅读,为了覆盖所有的知识点读到t页,这样的话如果从s+1开始阅读,那么必须读到t'>=t位置,尺取法。*/#include<set>#include<map>#include<cstdio>using namespace std;const int MAX = 1000005;int P,a[MAX];void solve(){    ///计算全部知识点的总数    set<int>all;    for(int i=0;i<P;i++) all.insert(a[i]);    int n=all.size();    ///尺取法    int s=0,t=0,num=0,res=P;    map<int,int>c; ///知识点一共出现多少次    for(;;){        while(t<P&&num<n){            if(c[a[t++]]++ == 0 ) ///出现新的知识点                num++;        }        if(num<n) break;        res=min(res,t-s);        if(--c[a[s++]]==0) ///某个知识点没了            num--;    }    printf("%d\n",res);}int main(){    while(~scanf("%d",&P)){        for(int i=0;i<P;i++) scanf("%d",&a[i]);        solve();    }    return 0;}


0 0