二分法博大精深
关键在于整数二分的时候+1-1的问题
Codevs1766装果子就是一道不容易看出来是二分法的题目
二分的关键是单调性
这个题假如是穷举的话,就从小到大去枚举包的空间的大小
当然,这种枚举是确定了上下界的枚举,下界就是最大水果堆的数量,上界就是所有水果数量之和
然后答案要求的是最小的能装下所有水果的包的大小,用多少包是确定的
由于限制了包的总数,那么包过大,虽然能装下尽可能多的水果,但是不满足题意
如果包过小,用的包的数量就会变多,可能超过题目给出的包的容量限制
我们这里要找的是一个临界值,可以看出它是有单调性的,而且肯定是有解的
这里可以二分
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int maxn=100005; 5 long long n,m; 6 long long ans; 7 long long a[maxn]; 8 bool check(long long v) 9 { 10 long long tot=0,tmp1=v,tmp2=m-1; 11 while(tot<n) 12 { 13 tot++; 14 tmp1-=a[tot]; 15 if(tmp1<0) 16 { 17 tmp1=v-a[tot]; 18 tmp2--; 19 if(tmp2<0) return false; 20 } 21 } 22 return true; 23 } 24 void ef(long long l,long long r) 25 { 26 long long m; 27 while(l<=r) 28 { 29 m=(l+r)/2; 30 if(check(m)) 31 { 32 r=m-1; 33 ans=m; 34 } 35 else l=m+1; 36 } 37 } 38 int main() 39 { 40 long long L=0,R=0; 41 scanf("%lld%lld",&n,&m); 42 for(int i=1;i<=n;i++) 43 { 44 scanf("%lld",&a[i]); 45 R+=a[i]; 46 L=max(L,a[i]); 47 } 48 ef(L,R); 49 printf("%lld",ans); 50 return 0; 51 }
这题是典型的二分答案了,二分法的题以后必须得补,太容易考也太重要了