• 【尺取法】


    尺取法

    POJ3061 Subsequence

    给定一个序列,使得其和大于或等于S,求最短的子序列长度。

    如果一个区间其和(ge S)了,那么不需要再向后推右端点了,因为其和也肯定(ge S)但长度更长,所以,当区间和(< S)时右端点向右移,和(ge S)时,左端点向右移以进一步找到最短的区间,如果右端点移动到区间末尾其和还不大于等于S,结束区间的枚举

    int main(){
    	int T;rd(T);
    	while(T--){
    		rd(n),rd(s);
    		for(int i=1;i<=n;++i) rd(a[i]);
    		int l=1,r=0;ans=inf,sum=0;
    		while(1){
    			while(r<n&&sum<s) sum+=a[++r];
    			if(sum<s) break;
    			ans=Min(ans,r-l+1),sum-=a[l++];
    		}
    		if(ans==inf) puts("0");
    		else printf("%d
    ",ans);
    	}
    	return 0;
    }
    

    POJ3320 Jessica's Reading Problem

    一本书有P页,每一页都一个知识点,求去最少的连续页数覆盖所有的知识点。

    如果一个区间的子区间满足条件,那么在区间推进到该处时,右端点会固定,左端点会向右移动到其子区间,且其子区间会是更短的,只是需要存储所选取的区间的知识点的数量,那么使用map进行映射以快速判断是否所选取的页数是否覆盖了所有的知识点

    int n,m,a[N];
    map<int,int>h;
    set<int> s;
    int main(){
    	rd(n);
    	for(int i=1;i<=n;++i) rd(a[i]),s.insert(a[i]);
    	m=s.size();
    	int l=1,r=0,ans=inf,nw=0;
    	while(1){
    		while(r<n&&nw<m) if(!h[a[++r]]++) ++nw;
    		if(nw<m) break;
    		ans=Min(ans,r-l+1);
    		if(--h[a[l++]]==0) --nw;
    	}
    	printf("%d",ans);
    	return 0;
    }
    

    luogu1638逛画展和它差不多

    int n,m,a[N],cnt[M];
    int main(){
    	rd(n),rd(m);
    	for(int i=1;i<=n;++i) rd(a[i]);
    	int l=1,r=0,nw=0,ans=inf,ansl,ansr;
    	while(1){
    		while(r<n&&nw<m) if(!cnt[a[++r]]++) ++nw;
    		if(nw<m) break;
    		if(ans>r-l+1) ans=r-l+1,ansl=l,ansr=r;
    		if(!--cnt[a[l++]]) --nw;
    	}
    	printf("%d %d",ansl,ansr);
    	return 0;
    }
    

    POJ2566 Bound Found

    给定一个数组和一个值t,求一个子区间使得其和的绝对值与t的差值最小,如果存在多个,任意解都可行。

    要找到一个子区间使得和最接近t的话,那么不断地找比当前区间的和更大的区间,如果区间和已经大于等于t了,那么不需要在去找更大的区间了,因为其和与t的差值更大,然后区间左端点向右移动推进即可。所以,首先根据计算出所有的区间和,

    排序之后按照上面的思路求解即可。

    int n,k,a[N];
    pii sum[N];
    int main(){
    	while(scanf("%d%d",&n,&k)!=EOF&&n+k){
    		sum[0]=pii(0,0);
    		for(int i=1;i<=n;++i) rd(a[i]),sum[i]=pii(sum[i-1].first+a[i],i);
    		sort(sum,sum+n+1);
    		for(int i=1;i<=k;++i){
    			int tmp=inf,st=0,ed=1,l,r;
    			ll ans,nw,x;
    			rd(x);
    			while(ed<=n){
    				nw=sum[ed].first-sum[st].first;
    				if(Abs(x-nw)<tmp) tmp=Abs(x-nw),ans=nw,l=sum[st].second,r=sum[ed].second;
    				if(nw>x) ++st;
    				else if(nw<x) ++ed;
    				else break;
    				if(st==ed) ++ed;
    			}
    			if(r<l) swap(r,l);
    			printf("%lld %d %d
    ",ans,l+1,r);
    		}
    	}
    	return 0;
    }
    

    SCOI2008生日礼物

    ==其实就是逛画展

    int n,m,cnt[100];
    struct node{int kind,po;}a[N];
    bool cmp(node A,node B){return A.po<B.po;}
    int main(){
    	rd(n),rd(m);
    	for(int j=1,i=0,x;j<=m;++j){
    		rd(x);
    		while(x--) a[++i].kind=j,rd(a[i].po);
    	}
    	sort(a+1,a+n+1,cmp);
    	int l=1,r=0,nw=0,ans=inf;
    	while(1){
    		while(r<n&&nw<m){
    			if(!cnt[a[++r].kind]++) ++nw;
    			while(a[r+1].po==a[r].po) if(!cnt[a[++r].kind]++) ++nw;
    		}
    		if(nw<m) break;
    		ans=Min(ans,a[r].po-a[l].po);
    		if(!--cnt[a[l++].kind]) --nw;
    		while(a[l+1].po==a[l].po) if(!--cnt[a[l++].kind]) --nw;
    	}
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    Objectivec中的@property和@synthesize详解
    objectc笔记
    iOS常用开源框架之ASIHTTPRequest
    oschina引用库说明
    UITableView的重用机制
    iOS常用开源框架之AFNetworking
    ObjectiveC中@class和#import的区别
    Python中文文档 目录(转载)
    关于Console 2窗口内容偏移以及中文输入的问题
    Python 中除法运算需要注意的几点
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11423049.html
Copyright © 2020-2023  润新知