1、使用的场景
求解符合条件的最小值或者最大值;
2、二分答案思路
对所有可能的答案进行折半查找,不断缩减范围,最终确定答案的方法;
3、求最小值
#include<bits/stdc++.h> using namespace std; int a[11]; bool check(int x){ return a[x]>=5; } int mmin(int L,int R){ int mid; while(L<R){ mid=(L+R)/2; if(check(mid)){ R=mid; }else{ L=mid+1; } } return L; } int main(){ for(int i=1;i<=10;i++){ cin>>a[i]; } sort(a+1,a+11); for(int i=1;i<=10;i++){ cout<<a[i]<<" "; } int ans=mmin(1,10); cout<<ans; return 0; }
4、求最大值
#include<bits/stdc++.h> using namespace std; int a[11]; bool check(int x){ return a[x]<5; } int mmax(int L,int R){ int mid; while(L<R){ mid=(L+R+1)/2; if(check(mid)){ L=mid; }else{ R=mid-1; } } return L; } int main(){ for(int i=1;i<=10;i++){ cin>>a[i]; } sort(a+1,a+11); for(int i=1;i<=10;i++){ cout<<a[i]<<" "; } int ans=mmax(1,10); cout<<ans; return 0; }
5、数列分段II【例子】
对于给定的一个长度为N的正整数数列A[i],现要将其分成M(M≤N)段,并要求每段连续,且每段和的最大值最小。
关于最大值最小:
例如一数列4 2 4 5 1要分成3段
将其如下分段:
[4 2][4 5][1]
第一段和为6,第2段和为9,第3段和为1,和最大值为9。
将其如下分段:
[4][2 4][5 1]
第一段和为4,第2段和为6,第3段和为6,和最大值为6。
并且无论如何分段,最大值不会小于6。
所以可以得到要将数列4 2 4 5 1要分成3段,每段和的最大值最小为6。
第1行包含两个正整数N,M,第2行包含N个空格隔开的非负整数A[i],含义如题目所述。
仅包含一个正整数,即每段和最大值最小为多少。
5 3 4 2 4 5 1
6
#include<bits/stdc++.h> using namespace std; int n,m,a[100010]; bool check(int x){ int tot=1; long long asum=0; for(int i=1;i<=n;i++){ if(asum+a[i]<=x)asum+=a[i]; else{ ++tot; asum=a[i]; } } return tot<=m; } int main(){ int L,R; L=0;R=0; cin>>n>>m; for(int i=1;i<=n;i++){ cin>>a[i]; L=max(L,a[i]); R+=a[i]; } while(L<R){ int mid=(L+R)/2; if(check(mid)){ R=mid; } else L=mid+1; } cout<<L; return 0; }
原文:https://www.cnblogs.com/myCPP/p/12089922.html