今天老師講了提了下尺取,於是就有了這篇筆記
ps:我覺得我們老師形容得很貼切,尺取就像蟲子蠕動一樣
給出乙個序列,求區間和大於或者等於s的最短區間長度.
3 2 8 10 5 3 8 4 2 9
i: 1 2 3 4 5 6 7 8 9 10
ai: 3 2 8 10 5 3 8 4 2 9
l: +
r: +
計算區間tot+=a[r] 再將r向前移動一位
得出tot=3,比s小,所以我們將r向後移動
i: 1 2 3 4 5 6 7 8 9 10
ai: 3 2 8 10 5 3 8 4 2 9
l: +
r: +
計算區間tot+=a[r] 再將r向前移動一位
得出tot=5,比s小,繼續移動r
i: 1 2 3 4 5 6 7 8 9 10
ai: 3 2 8 10 5 3 8 4 2 9
l: +
r: +
計算區間tot+=a[r] 再將r向前移動一位
得出tot=13,比s小,繼續移動r
i: 1 2 3 4 5 6 7 8 9 10
ai: 3 2 8 10 5 3 8 4 2 9
l: +
r: +
計算區間tot+=a[r] 再將r向前移動一位
得出tot=13,比s小,繼續移動r
i: 1 2 3 4 5 6 7 8 9 10
ai: 3 2 8 10 5 3 8 4 2 9
l: +
r: +
計算區間tot+=a[r] 再將r向前移動一位
得出tot=23,比s大,停止移動r,記錄當前區間長度k=4
i: 1 2 3 4 5 6 7 8 9 10
ai: 3 2 8 10 5 3 8 4 2 9
l: +
r: +
因為r已經不能再移動,因此我們移動l
計算區間tot-=a[l] 再將l向前移動一位,因為原本l所在位置已經不屬於這個區間了
得出tot=20,比s大,r繼續不動,記錄當前區間長度k=3
i: 1 2 3 4 5 6 7 8 9 10
ai: 3 2 8 10 5 3 8 4 2 9
l: +
r: +
計算區間tot-=a[l] 再將l向前移動一位
得出tot=18,比s大,r繼續不動,記錄當前區間長度k=2
i: 1 2 3 4 5 6 7 8 9 10
ai: 3 2 8 10 5 3 8 4 2 9
l: +
r: +
計算區間tot-=a[l] 再將l向前移動一位
得出tot=10,比s小,重新移動r
i: 1 2 3 4 5 6 7 8 9 10
ai: 3 2 8 10 5 3 8 4 2 9
l: +
r: +
計算區間tot+=a[r] 再將r向前移動一位
得出tot=15,等於s,r不動,移動l,記錄區間長度k=2
觀察這個過程,這就是尺取法了,如果把l看做蟲的尾巴,r看做蟲的頭,那麼完全就是乙個蠕動的過程:
l_/\_r
先向右延伸區間
l_____r
到達邊界後向左縮小區間
l_/\_r
l_____r
l_/\_r
l_____r
以下是毒瘤**實現:#include#define re register
#define ios ios::sync_with_stdio(false)
#define (x) [x]
#define cin(x) cin>>x
#define cout(x) cout<#define endl puts(" ")
#define ww(i,j) while(i<=j)
#define ww(i1,j1,i2,j2) while(i1#define b break;
#define length(l,r) r-l+1
#define mmiinn(a,b) a<=b?a:b
#define inf 2147483647
#define f(s,j) for(int i=s;i<=j;++i)
#define r return
#define i(i,j) if(iusing namespace std;
int s,n,a[1000001],l=1,r=0,now=0,ans=inf;
int main ()
cout(ans);
endl;
r 0;
}
尺取法學習筆記
返回的推進區間開頭和結尾,求滿足條件的最小區間的方法稱為尺取法。尺取法,顧名思義,像尺子一樣,一塊一塊的擷取。用尺取法來優化,使複雜度降為了o n 整個過程分為四步 1.初始化左右端點 2.不斷擴大右端點,直到滿足條件 3.如果第二步中無法滿足條件,則終止,否則更新結果 4.將左端點擴大1,然後回到...
尺取法學習
參考資料 挑戰程式設計競賽 p146 參考部落格 介紹 尺取法 顧名思義,像尺子一樣取一段,借用挑戰書上面的話說,尺取法通常是對陣列儲存一對下標,即所選取的區間的左右端點,然後根據實際情況不斷地推進區間左右端點以得出答案。之所以需要掌握這個技巧,是因為尺取法比直接暴力列舉區間效率高很多,尤其是資料量...
ACM 學習記錄 尺取法
給定乙個陣列和乙個數s,在這個陣列中找乙個區間,使得這個區間之和等於s。例如 給定的陣列int x 14 和乙個s 15。那麼,可以找到的區間就應該有0到4,3到5,6到7.注意這裡的下標從0開始 對於這樣的題,不用任何技巧就可以跑出結果,例如下面這個方法可能是大多數人能夠想出來的 先用乙個陣列su...