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 }