二分+贪心(7)
二分+贪心
我的天,最近也不知道忙点什么,课也基本没有,还是累的要死。
这篇写二分和贪心。
先说二分吧。二分:二分查找和二分搜索,二分查找:是一种非常高效的搜索方法,主要原理是每次搜索可以抛弃 一半的
值来缩小范围。
怎么说呢,二分真的是不难,关键在于你得能看出他是二分思想,有些题真的是想不到居然能用二分,而且用二分会这么简单。
老规矩,先给一个二分的板子
int L;//左边界 int R;//右边界 while(L<=R) { int mid=(L+R)/2; if(a[mid]==k) //k就是想找的那个数 { flag=mid; break; } else if(a[mid]>k) R=mid-1; else L=mid+1; }
再给一个二分的板子题(真的是找不见简单的):
Strange fuction HDU - 2899
#include <bits/stdc++.h> using namespace std; typedef long long ll; double f(double x,double y) { return (double)6.0*pow(x,7.0)+8.0*pow(x,6.0)+7.0*pow(x,3.0)+5.0*pow(x,2.0)-y*x; } double g(double x,double y) { return 42.0*pow(x,6.0)+48*pow(x,5.0)+21*pow(x,2.0)+10*x-y; } int main() { double x,y; int T; cin>>T; while(T--) { cin>>y; double l=0.0,r=100.0; double mid; while(r-l>1e-6) { mid=(l+r)/2; if(g(mid,y)<0) l=mid; else r=mid; } printf("%.4f\n",f(mid,y)); } return 0; } //读者自己理解吧,反正也不算难。
拓展:
lower_bound(), upper_bound()
真香!!!这个是真的香。
在从小到大的排序数组中,
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
在从大到小的排序数组中,重载lower_bound()和upper_bound()
lower_bound( begin,end,num,greater() ):从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num,greater() ):从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
看下边的代码理解一下哈:
#include <bits/stdc++.h> using namespace std; typedef long long ll; int main() { //从小到大的排序数组 int a[12]={3,4,5,5,5,6,6,17,18,19,110,111}; cout<<lower_bound(a,a+12,17)<<endl; //0x6ffdfc cout<<lower_bound(a,a+12,17)-a<<endl; //7 cout<<a[lower_bound(a,a+12,17)-a]<<endl; //17 cout<<upper_bound(a,a+12,17)<<endl; //0x6ffdf0 cout<<upper_bound(a,a+12,17)-a<<endl; //8 cout<<a[upper_bound(a,a+12,17)-a]<<endl; //18 //从大到小的排序数组 int b[11]={9,8,8,8,7,6,5,4,3,2,1}; cout<<lower_bound(b,b+11,7,greater<int>())<<endl; //0x6ffd80 cout<<lower_bound(b,b+11,7,greater<int>())-b<<endl; //4 cout<<b[lower_bound(b,b+11,7,greater<int>())-b]<<endl; //7 cout<<upper_bound(b,b+11,7,greater<int>())<<endl; //0x6ffd54 cout<<upper_bound(b,b+11,7,greater<int>())-b<<endl; //5 cout<<b[upper_bound(b,b+11,7,greater<int>())-b]<<endl; //6 return 0; }
先来个板子题(虽然可以二分,但是建议感受一下真香):
pairs HDU - 5178
#include<bits/stdc++.h> using namespace std; typedef long long ll; int a[100010]; int main() { ios::sync_with_stdio(false); int t; ll n,k; cin>>t; while(t--) { ll ans=0; cin>>n>>k; for(int i=0;i<n;i++) cin>>a[i]; sort(a,a+n); for(ll i=0;i<n;i++) { ll l=lower_bound(a,a+n,a[i]-k)-a; ll r=upper_bound(a,a+n,a[i]+k)-a-1; ans=ans+(r-l); } cout<<ans/2<<endl; } return 0; }
二分+贪心先关题目:
Pie HDU - 1969
Best Cow Line POJ - 3617
Trailing Zeroes (III) LightOJ - 1138
The Frog’s Games HDU - 4004 (难)
湫湫系列故事——消灭兔子 HDU - 4544(难)
Strange fuction HDU - 2899
Can you find it? HDU - 2141
Radar Installation POJ - 1328 (难)
Aggressive cows POJ - 2456
River Hopscotch POJ - 3258 (难)
再说贪心,反正在我看来,贪心就是玩了个脑子数学加C++基础,要熟练的运用这些东西,贪心才能贪的得心应手。也没有什么具体的方法板子,反正做出来就行。就像上面的题,每个题都用到贪心。还有就是用贪心做题一定要把方方面面考虑周到,否则很容易WA掉。
- 点赞
- 收藏
- 分享
- 文章举报
- 修路&&牛.. 贪心+二分..
- codeforce 551C GukiZ hates Boxes(二分+贪心)
- CodeForces - 551C (二分查找答案+贪心)
- 【Educational Codeforces Round 3 D】【二分答案 贪心排序】Gadgets for dollars and pounds m个物品n天价格买k个的最早天数
- POJ-3258 River Hopscotch 二分查找+贪心
- POJ - 3122 Pie (二分+贪心 计算个数)
- 列车调度(贪心+二分)
- TOJ 1644: Cow Acrobats -- 二分,贪心
- Codeforces Round #307 (Div. 2) C. GukiZ hates Boxes 贪心/二分
- BZOJ 2241([SDOI2011]打地鼠-二分判断+贪心)
- [POJ](2456)Aggressive cows ---二分查找+贪心(查找+贪心)
- HDU4004 The Frog's Games【贪心+二分搜索】
- [NWPU][2014][TRN][5]二分和贪心 HDU 4296
- CodeForces - 732D Exams(二分+贪心)
- uvalive3971(二分+贪心)
- Gym 100886J Sockets(二分+贪心)
- work (二分 贪心)
- zoj 3820 Building Fire Stations(贪心 + 二分)
- UVa 714 Copying Books 二分 + 贪心 (最大值最小化问题)
- 二分贪心专题总结