分石子

分石子

http://www.nowcoder.com/questionTerminal/1ea5b4eaeff841a4918931791b000756

分石子问题

题解源自:牛客大佬——745599318

思路:
#令res表示分裂后m堆的最小值,
#res一定在[1, min{a[i], i=0,1...,n-1}]区间内,记左右区间分别为left, right。
#mid初始值去区间中值,即mid=left+(right-left)/2,利用二分思想不断找到mid的最终值。
#因为要求最小值最大,所以分堆的时候会尽量使每一堆的数据尽量均匀且接近最小值mid,
#具体地,对于其中一对a[i],在最小堆值为mid的条件下,最多可分为a[i]/mid堆。
#记所有堆可分别的堆数位cnt(a[0]/mid+....+a[n-1]/mid),
#若cnt<m,堆数不够,需减小mid,设右边界right=mid-1;
#若cnt>m,需增大mid,设左边界left=mid+1;
#若cnt==m,也不一定就是最终答案,因为mid稍微增大一点可能cnt的值并不会改变,还要继续向后找,left=mid+1.

class Solution:
    def solve(self , n , m , a ):
        if n == m: return min(a)
        left, right = 1, min(a)
        while left<right:
            mid = (left+right+1) >> 1  #二分法取mid值;
            total = sum(nums//mid for nums in a) #当mid为分m堆后的最小值时,共可以分total堆;
            if total >= m:
                left = mid  #当最小值为mid的时候,堆数大于等于m,说明mid可能最小值中的最大也可能不是,说不定mid也满足total = m;
            else:
                right = mid-1 #total小于m,说明mid大了,分得堆数小于m,需要减小m
        return left
全部评论

相关推荐

01-02 00:50
三峡大学 Java
程序员牛肉:这简历一出手就离失业不远了。 作为一家公司来讲,我如果要招日常实习生,那我对实习生最基本的要求就是要能干活,毕竟你就待三四个月,谁会留心培养你? 那么除了院校之外,最重要的就是项目和实习了。没有实习的话项目就好好搞。 但是你说你这个项目吧:课程作业管理系统和TMS运输管理系统。这两个基本就和闹着玩差不多。 你作为一个想要应聘Java开发实习生的人,对后端的理解还仅仅停留在:“使用mapper和sql映射”,“使用SQL进行多表调用”,“基于MySQL简历表结构”,“基于Spring boot完成CURD操作”这种玩具上......... 找不到后端实习的
点赞 评论 收藏
分享
评论
3
1
分享

创作者周榜

更多
牛客网
牛客企业服务