二分题最大值最小化的模式:
设[l,r],l为最小可能(表示不一定可行)可行数,r为最大可行数。设mid,然后check(mid),依照题目意思,不可行则l=mid+1,否则r=mid。
参考程序:
3273:
#include<cstdio>
#define maxn 110000
typedef long long LL;
LL in[maxn];
int n,m;
bool Check(int k){
LL sum=0;
int cnt=1;
for (int i=0;i<n;i++){
if (in[i]>k)return true;
if (sum+in[i]<=k)sum+=in[i];
else {sum=in[i];cnt++;}
}
return cnt>m;
}
int main(){
scanf("%d%d",&n,&m);
LL r=0;
for (int i=0;i<n;i++){
scanf("%lld",&in[i]);
r+=in[i];
}
LL l=0;r++;
while (l<r){
LL mid=(l+r)>>1;
if (Check(mid))l=mid+1;
else r=mid;
}
printf("%lld\n",l);
return 0;
}
3104:
#include<cstdio>
#include<algorithm>
#define maxn 210000
using namespace std;
int a[maxn];
int n,k;
bool Check(int time){
long long need=0;
for (int i=0;i<n;i++)
if (a[i]-time>0)need+=(a[i]-time+k-1)/k;
return need>time;
}
int main(){
scanf("%d",&n);
int r=0;
for (int i=0;i<n;i++)
scanf("%d",&a[i]);
scanf("%d",&k);
k--;
if (k==0)printf("%d",*max_element(a,a+n));else{
int l=0;
r=*max_element(a,a+n);
while (l<r){
int mid=(l+r)>>1;
if (Check(mid))l=mid+1;
else r=mid;
}
printf("%d",l);
}
return 0;
}