二分模板

二分答案本质已经出来了

 

题型1,最值最化

就是每次根据m次比较,找最值(只要有m次操作,有序单调基本都可用)

 

最小最大和最大最小略有不同(走的方向更新解的方向刚好相反,理解了本质都一样)

 

关键和难点还是写judge函数怎么找到每次枚举答案的次数,怎么找到写出m次。

 

 1     while(l<=r)//最小值最大化
 2     {
 3         ll mid=(l+r)/2;
 4  
 5         int t=judge(mid);
 6         if(t<=m)//t<=是不变的,<=m都是可行解,ans必定放在这里更新
 7         {
 8             l=mid+1;//往右区间高方向试试能不能更大解
 9             ans=mid;
10         }
11         else r=mid-1;
12     }
13     
14     while(l<=r)//最大值最小化
15     {
16         ll mid=(l+r)/2;
17  
18         int t=judge(mid);
19         if(t<=m)//t<=m是不变的,<=m次都是可行解,ans必定放在这里更新
20         {
21             r=mid-1;//往左区间低方向试试能不能更小解
22             ans=mid;
23         }
24         else l=mid+1;
25     }

 

题型2,有小数点类型(保留几位小数==)的求解,这种求一个答案,不断试答案枚举答案!

 

与题型1略有不同,到大致一样,遇到满足的即可马上退出,不像题型1一样遇到满足的不退出再试试有没有更大(小)的更优解!

小车问题模板代码(银行贷款问题也一样)(比较考验代码能力和思维能力==分析解决问题的能力)

 1 #include <iostream>
 2 #include <iomanip>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     ios::sync_with_stdio(false); cin.tie(0);
 8     
 9     double s,a,b;
10     cin>>s>>a>>b;
11     
12     double ans=0;
13     double l=0,r=s;
14     while(l<=r)
15     {
16         double mid=(l+r)/2;
17 
18         double t2=mid/b+(s-mid)/a;
19         double t1=mid/b+(mid-a*mid/b)/(a+b)+(s-a*mid/b-a*(mid-a*mid/b)/(a+b))/b;
20         double t=t2-t1;
21         
22         if(t>=-0.000001 && t<=0.000001)
23         {
24             ans=mid;
25             break;
26         } 
27         else
28         {
29             if(t<-0.000001) r=mid-0.000001;
30             else if(t>0.000001) l=mid+0.000001;
31         }
32              
33     }
34     //if(l>r) ans=r;
35     
36     //cout<<setiosflags(ios::fixed)<<setprecision(6)<<ans<<endl;
37     double p=ans/b+(s-ans)/a;
38     cout<<setiosflags(ios::fixed)<<setprecision(6)<<p<<endl;
39     
40     
41     return 0;
42 }

 

posted @ 2018-11-09 22:58  RedBlack  阅读(171)  评论(0编辑  收藏  举报