尺取法 求滿足條件的最小區間

2021-08-28 08:13:43 字數 2457 閱讀 9260

給n個數 乙個s  求總和大於等於s的連續子串行的長度最小值,不存在輸0

一開始想暴力: for遍歷起點   for(1長度到可以的長度) tle

上面的想法就是確定   起點  終點

現在通過乙個sum【i】=a0+。。。ai-1    這個字首和    把一段連續子串行表達成兩個字首和的差值

即  as+。。。。at-1 = sum【t】 - sum【start】

因此得到乙個式子   sum【t】 - sum【start】>= s

由於sum這個陣列 是從小到大的   所以可以二分

轉換成sum【t】 >= s + sum【start】不知道這是不是所謂的   離散化

所以思路:  遍歷起點start  找這樣乙個  t

const int maxn = 1e5 + 100;

int sum[maxn];//sum[i] a0 +.....ai-1

int n, s;

void solve()

int res = n;//該題最大就是全部數 即n長度

//sum 是字首和 從小到大的

//中間判斷 如果一旦大於 全部數的和 那肯定找不到

for (int start = 1; /*start <= n*/sum[start] + s <= sum[n]; ++start)

cout << res << endl;

}int main()

solve();

}}

演算法解釋在 挑戰p148頁

取法:顧名思義,像尺子一樣取一段,借用挑戰書上面的話說,尺取法通常是對陣列儲存一對下標,即所選取的區間的左右端點,然後根據實際情況不斷地推進區間左右端點以得出答案。之所以需要掌握這個技巧,是因為尺取法比直接暴力列舉區間效率高很多,尤其是資料量大的時候,所以尺取法是一種高效的列舉區間的方法,一般用於求取有一定限制的區間個數或最短的區間等等。當然任何技巧都存在其不足的地方,有些情況下尺取法不可行,無法得出正確答案。

使用尺取法時應清楚以下四點:1、 什麼情況下能使用尺取法? 2、何時推進區間的端點? 3、如何推進區間的端點? 3、何時結束區間的列舉?

const int maxn = 1e5 + 100;

int a[maxn], n, s;

void solve()

if (sum < s) break;//如果退出迴圈後 找不到符合條件的 就退出 因為上面已經加到不能再加

res = min(res, end - start);

sum -= a[start++];//減去前的 往後移動

} if (res == n + 1)

res = 0;

cout << res << endl;

}int main()

}

two point   尺取法

題意:給一些連續區間塊   在這裡面 飛行員能平滑   不在就會以y = -x + b 直線 下降

讓你找乙個最長區間【i,j】長度      i點開始跳   j點是落地 

首先:貪心一定是在每個連續區間塊 最左邊開始跳的

因為如果你在區間內跳  反而少了一些水平距離  

在外跳的話  會下落 再到區間的最左邊  所以很容易知道這個結論

還有h只跟  每兩個連續區間塊之間 的距離有關

for(遍歷起點 即每個區間最左邊)

while(加到落地 求過了多少個連續區間塊)   。。。。。tle   每次都求和一遍

所以改用尺取法 

#include#includeusing namespace std;

#define inf 0x3f3f3f3f

const int maxn = 2e5 + 100;

int a[maxn], b[maxn], seg[maxn], interval[maxn];

int main()

int res = -inf;

int hh, tmp, start, end;

hh = tmp = 0;

start = end = 1;

while (1)

//不是最後乙個間距就加

hh += interval[end + 1];

end++;

}res = max(res, tmp + h);//tmp就是 這乙個 連續區間 的seg和 下降距離即 hh + (h - hh) 即h

if (end == n + 1) break;

hh -= interval[start + 1];//減前面 尺取法

tmp -= seg[start++];

}cout << res << endl;

} return 0;

}

尺取法(單調性 找區間個數或最小區間)

尺取法只能具有單調性的資料 反覆地推進區間的開頭和末尾,來找滿足條件的最小區間 一般要求個數或者是最小的 右端到臨界狀態後,判斷是否滿足條件,更新結果 左端右移 num具有單調性,可用尺取法 include includeusing namespace std include include inc...

14 求滿足條件的3位數

總時間限制 1000ms 記憶體限制 65536kb 描述編寫程式,按從小到大的順序尋找同時符合條件1和2的所有3位數,條件為 1.該數為完全平方數 2.該數至少有2位數字相同 例如,100同時滿足上面兩個條件。輸入輸入乙個數n,n的大小不超過實際滿足條件的3位數的個數。輸出輸出為第n個滿足條件的3...

求m區間的最小值

乙個含有n項的數列 n 2000000 求出每一項前的m個數到它這個區間內的最小值。若前面的數不足m項則從第1個數開始,若前面沒有數則輸出0。第一行兩個數n,m。第二行,n個正整數,為所給定的數列。n行,第i行的乙個數ai,為所求序列中第i個數前m個數的最小值。6 27 8 1 4 3 207 71...