算法初步——尺取法
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
给定长度为n(10 < N < 100 000)的数列整数 a0,a1,…,an-1以及整数S(S < 100 000 000)。求出 总和不小于S的连续子序列的长度的最小值。如果 解不存在,则输出0。
样例: n=10 S=15 a={5,1,3,5,10,7,4,9,2,8}
5
1
3
5 10 7
4
尺取法
——算法初步
描述
尺取法通常是指对数组保存保存一 对下标(起点,终点),然后根据实际 情况交替推进两个端点直到得出答案的 方法。
例题
给定长度为n(10 < N < 100 000)的数列整数 a0,a1,…,an-1以及整数S(S < 100 000 000)。求出 总和不小于S的连续子序列的长度的最小值。如果 样例: 解不存在,则输出 0。 n=10
S=15 a={5,1,3,5,10,7,4,9,2,8}
0 5
5 1
6 3
9 14 24 31 35 44 46 54 5 10 7 4 9 2 8
①求出sum(i)=a0+a1+…+ai-1 ②二分搜索满足条件的最小值
O(n)
方法一:二分法
int n,S; int a[MAX_N]; int sum[MAX_N+1]; void solve(){ //计算sum for(int i=0;i<n;i++){ sum[i+1]=sum[i]+a[i]; } if(sum[n]<S){ O(nlogn) //解不存在 printf("0\n"); return ; } int res=n; for(int s=0;sum[s]+S<=sum[n];s++){ //利用二分搜索求出t int t=lower_bound(sum+s,sum+n,sum[s]+S)-sum; res=min(res,t-s); } printf("%d\n",res); }
O(n)
POJ 2566 Bound Found
POJ 3320 Jessica's Reading Problem
HDU 1058 Humble Numbers
Thaห้องสมุดไป่ตู้k
you!
9
2
8
方法二:尺取法
int n,S; int a[MAX_N]; int sum[MAX_N+1]; 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); }