51NOD 1128正整数分组V2 二分答案

这道题是典型的二分答案法。但是首先难道这道题的时候我进行了一系列的思考,甚至联想到了之前多校中类似于树状划分的问题。。。原因是大家都包括N各节点K个输入。。

实际上最开始联想到了应当使用二分法“枚举”正确答案,但是实际上手的时候却没有想到应当怎么处理是否大于的反馈问题。。。甚至都没有很好的定义区间的含义。。。对于如何分配最大值的取值甚至开始构思背包问题的解决方案,试图匡算时间复杂度。。。。

然而。。。。万万没想到。。。。这TM是连续的。。。。意味着可以直接使用贪心来判断是否合法,用进行玩划分之后的剩余集合的数量来进行进行反馈——多了还是少了

在构造二分函数的时候应当注意:此时的语境是:“在合法区间内选择最小的” 与此同时 使用二分法搞出来的实际上是“合法和非法区间的交界线”,如果返回A就是非法区间的最后一个,但是返回B就是合法区间的第一个,在这个相对特殊的语境下,应当对函数作适当的返回。

 有另外其实lower_bound()和upper_bound()的区别有点类似与上述的场景。。。。

然而。。。。突然发祥之前给队友讲错了。。。赶紧去纠正了下、

 

放上AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const long long MAXN=50233;
 4 long long a[MAXN];
 5 long long k,n;
 6 long long h=0;
 7 
 8 void init()
 9 {
10     cin>>n>>k;
11     for(int i=0;i<n;++i)
12     {
13         cin>>a[i];
14         h+=a[i];
15     }
16 }
17 long long com(long long key)
18 {
19     long long summ=0;
20     long long kk=k;
21     for(int i=0;i<n;++i)
22     {
23         if(summ+a[i]>key)summ=a[i],kk--;
24         else summ+=a[i];
25     }
26     return kk;
27 }
28 long long bin_search(long long a,long long b)
29 {
30     
31     
32     if(a==b-1)return b;
33     long long mid=(a+b)/2;
34 //    cout<<a<<ends<<b<<ends<<com(mid)<<endl;
35     if(com(mid)<=0)return bin_search(mid,b);
36     else return bin_search(a,mid);
37 }
38 int main()
39 {
40     cin.sync_with_stdio(false);
41     init();
42     cout<<bin_search(1,h);
43     return 0;
44 }

 

posted @ 2017-08-18 16:47  六花的邪王真眼  阅读(330)  评论(0编辑  收藏  举报