分组

题目描述
牛牛有一个n个数字的序列a1a2…an,现在牛牛想把这个序列分成k段连续段,牛牛想知道分出来的k个连续段的段内数字和的最小值最大可以是多少?
示例1
输入
复制
4,2,[1,2,1,5]
输出
复制
4
说明
有3种分法
[1],[2,1,5],数字和分别为1,8,最小值为1
[1,2][1,5],数字和分别为3,6,最小值为3
[1,2,1],[5]数字和分别为4,5,最小值为4
则最小值的最大值为4

bool check(int k, int mid, vector<int>	&a) {
	int temp = 0;
	for (int i = 0; i < a.size(); i++)
	{
		temp += a[i];
		if (temp >= mid)
		{
			k--;
			temp = 0;
		}
	}
	//判断是否能分的完
	//若k>0则证明可以分的完,则说明极限值过大。
	//k<0则表明不可以分完,则说明值过小.
	if (k>0)
	{
		return false;
	}
	return true;
}
    /**
     * 分组
     * @param n int整型 
     * @param k int整型 
     * @param a int整型vector 
     * @return int整型
     */
    int solve(int n, int k, vector<int>& a) {
        	int right = 0;
	for (int i = 0; i < n; i++)
		right += a[i];
	int left = 0;
	//若分为K段 则必然最小值的最大值不超过[0,right]
	right /= k;
	//则可能存在的分段极限值为[left,right]之间存在.
	int mid = (left + right) >> 1;
	while (mid > left) {
		if (check(k, mid, a))
		{
			//分段值过小,需增大
			left = mid;mid = (left + right) >> 1;
		}
		else {
			//分段值过大,还需减小.
			right = mid; mid = (left + right) >> 1;
		}
	}
	if (check(k, right, a))
		return right;
	else
		return left;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值