Day 1 二分搜索训练总结
????? 其實二分是一個重要的思想,有些題目不一定一眼就能看出二分,需要根據特定的條件選擇正確的解法,有時二分答案時驗證很簡單,有時卻不那么容易。一般來說,在最大(小)的條件下找一個最小(大)的解的時候可以用二分,一些線性函數也可以用二分搜索求解這種題目比較容易看出來。
???? 今天做的題目都是二分的題目,還有兩道三分,但感覺那兩道題目再推出函數之后就可以求導求解了,感覺(當然也因為現在見的題目比較少)用到三分的都是數學題,而二分思想卻是很重要的東西,三分的數學題目一般都是凸函數,這時候求導的話導數一般是單調的,求導數的零點就可以用二分去寫。
?
今天訓練的收獲有以下幾點:
1、 離散型單調解、單調序列的二分搜索的模板,保證以后能不打錯邊界條件之類的。
2、 連續型函數的二分搜索模板。
3、 三分搜索模板。
4、 Map、Vector、運算符重載等C++特性的簡單應用和熟悉。
下面是今天AC的題目的簡要說明
HOJ 1604 Cable Master??????? 將小數*100轉化成離散型整數的二分搜索,題目有無解情況,
??????????????????????????????????????? 沒注意造成一直被零除比較囧。
HOJ 2160 bin packing????????? 很水的題目,直接貪心。
HOJ 2278 IP Filtering?????????? 按照ip段左端點排序,并合并重疊的ip段,然后再二分查找就行了。
HOJ 2608 Assemble??????????? 二分答案,主要是處理數據比較麻煩,學習使用了map容器,用
?????????????????????????????????????? <string,<vector<pair<int,long long> > >做元素,代碼很簡潔。
HOJ 2651 PIE???????????????????? 離散型二分搜索,可以用來當做以后用的模板了。
POJ 3685 Matrix???????????????? 很經典的二分轉化,根據題意,發現矩陣的每一列都是按照行來遞增的,二分答案,
??????????????????????????????????????? 計算每一列中比這個解小的數的總數,計算的時候可以繼續二分搜索,
??????????????????????????????????????? 但又因為列確定,用解一元二次不等式的方法求出小于等于這個解的兩個行標,
??????????????????????????????????????? x2-x1+1就是這一行中比這個數小的數的總數。
POJ 3737 UmBasketella?????? 三分搜索,給出表面積S=π*R*R+π*R*L(l為側面邊長),r最大為sqrt(s/2π),
??????????????????????????????????????? 枚舉這個r,v就很好表示了,其實也可以求導來算出v的最大值。
ZOJ 3202 Light Bulb?????????? 三分搜索,推導出公式l = (h*D-x*H)/(D-x)+x,枚舉x即可。
?
附上 HOJ2608 Assemble 的代碼
#include<vector> #include<cstdio> #include<map> #include<string>using namespace std; typedef long long longint; const long long INF = 1<<30;bool check(const map<string,vector<pair<int,longint> > > &m, longint B, longint Q) {longint b = 0LL;for (map<string,vector<pair<int,longint> > >::const_iterator it = m.begin(); it != m.end(); it++){const vector<pair<int,longint> > &v = it->second;longint x= INF;for (vector<pair<int,longint> >::const_iterator jt = v.begin(); jt != v.end(); jt++)if (jt->second >= Q)x = min(x,(long long)jt->first);if (x == INF) return 0;b += x;if (b > B) return 0;}return 1; }int main() {int T, n;longint b;scanf("%d", &T);while(T--){scanf("%d%lld", &n,&b);map<string,vector<pair<int,longint> > > m;for (int i = 0; i < n; i++){char type[30], name[30];int price;longint quality;scanf("%s %s %d %lld", type, name, &price, &quality);m[type].push_back(make_pair(price,quality));}longint l=0LL, r = 1000000000LL, mid,ans;while(l <= r){mid = (l+r)/2LL;if (check(m,b,mid)){ans = mid;l = mid + 1LL;}else r = mid - 1LL;}printf("%lld\n", ans);} }轉載于:https://www.cnblogs.com/ijingo/archive/2012/07/23/2605557.html
總結
以上是生活随笔為你收集整理的Day 1 二分搜索训练总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 4.1最终版SDK和AD
- 下一篇: eclipse自动补全的设置