您的位置:首页 > 其它

二分+贪心(7)

2020-02-02 19:46 225 查看

二分+贪心

我的天,最近也不知道忙点什么,课也基本没有,还是累的要死。
这篇写二分和贪心。
先说二分吧。二分:二分查找和二分搜索,二分查找:是一种非常高效的搜索方法,主要原理是每次搜索可以抛弃 一半的
值来缩小范围。
怎么说呢,二分真的是不难,关键在于你得能看出他是二分思想,有些题真的是想不到居然能用二分,而且用二分会这么简单。
老规矩,先给一个二分的板子

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掉。

  • 点赞
  • 收藏
  • 分享
  • 文章举报
〆℡小短腿走快点ゝ 发布了30 篇原创文章 · 获赞 1 · 访问量 1421 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: