給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...