标签:
二分.
最小化最大值.
和"河中跳房子","Agressive Cows"等最大化最小值问题正好相反的最小化最大值问题,同样用二分解决,原理基本相同,差别主要在C条件的判断上.
1.最大化最小值:
相当于n个东西分给m个人,使得每个人至少拿x个,那么每个人拿够了就走,给后面的人多留一点,只要能分够>=m个人就是true,多的全扔给最后一个人就是了.
2.最小化最大值:
相当于n个东西分给m个人,每个人至多能拿x个,那么每个人尽可能多拿一点,给后面的人少留一点,只要能使<=m个人分完这n个东西就是true,之后每个人随便拿一点给没有拿到的人就是了.
注意:
1.如上所述两种问题的区别.
2.关于初始值.有些题直接给前缀和(如之前提到的两题),那样最小值的最大值就是平均值,最大值的最小值也是平均值,但像这道题,如果算sum可能会炸,而且不知道会炸到啥程度,所以不能瞎搞,只能乖乖设定y为0x7fffffff,x为单点最大值.
对于可以计算sum的题有:
<1>.最大化最小值:
x为单点最小值,y为平均值.
<2>.最小化最大值:
x为平均值与单点最大值两者中大的那一个,y为sum.其实直接令x=0,y=0x7fffffff即可,不过循环32次而已...
PS.看懂别人的代码不重要,重要的是要理解算法的思想,不同的代码只是实现算法的方式不同与个人喜好问题而已,要真正想明白,把东西转化成自己的.
1 #include<cstdio> 2 #include<algorithm> 3 using std :: max; 4 5 const int maxn=100005; 6 int n,m,maxa=0; 7 int a[maxn]; 8 9 void init() 10 { 11 scanf("%d%d",&n,&m); 12 for(int i=1;i<=n;i++) 13 { 14 scanf("%d",&a[i]); 15 maxa=max(maxa,a[i]); 16 } 17 } 18 19 bool C(int x) 20 { 21 int sum=0,ans=1; 22 for(int i=1;i<=n;i++) 23 { 24 sum+=a[i]; 25 if(sum>x) 26 { 27 sum=a[i]; 28 ans++; 29 } 30 } 31 if(ans<=m) return true; 32 return false; 33 } 34 35 void solve() 36 { 37 int x=maxa,y=0x7fffffff; 38 while(x<y) 39 { 40 int m=x+(y-x)/2; 41 if(C(m)) y=m; 42 else x=m+1; 43 } 44 printf("%d\n",x); 45 } 46 47 int main() 48 { 49 freopen("monthly.in","r",stdin); 50 freopen("monthly.out","w",stdout); 51 init(); 52 solve(); 53 fclose(stdin); 54 fclose(stdout); 55 return 0; 56 }
标签:
原文地址:http://www.cnblogs.com/Sunnie69/p/5423817.html