数组分段和最大值最小问题

参考博文:https://blog.csdn.net/littlestream9527/article/details/12242155

原始问题:
假设有m个房间,清洁每个房间耗时用一个数组表示,10、20、30、40、50、60、70、80、90,安排n个清洁工,将连续的房间分成n份,每部分耗时求和,其最大值为此种分法的总耗时。求最快的耗时是多少。例如3个清洁工的话,10 20 30 40 50 | 60 70 | 80 90,此时是最快的,耗时为170。

分析:

此题可以想象成把数据按顺序装入桶中,m即是给定的桶数,问桶的容量至少应该为多少才能恰好把这些数装入n个桶中(按顺序装的)。

二分法思想求解:

首先我们可以知道,桶的容量最少不会小于数组中的最大值,即桶容量的最小值(小于的话,这个数没法装进任何桶中),假设只需要一个桶,那么其容量应该是数组所有元素的和,即桶容量的最大值;其次,桶数量越多,需要的桶的容量就可以越少,即随着桶容量的增加,需要的桶的数量非递增的(二分查找就是利用这点);我们要求的就是在给定的桶数量m的时候,找最小的桶容量就可以把所有的数依次装入k个桶中。在二分查找的过程中,对于当前的桶容量,我们可以计算出需要的最少桶数requiredPainters,如果需要的桶数量大于给定的桶数量k,说明桶容量太小了,只需在后面找对应的最小容量使需要的桶数恰好等于k;如果计算需要的桶数量小于等于k,说明桶容量可能大了(也可能正好是要找的最小桶容量),不管怎样,该桶容量之后的桶容量肯定不用考虑了(肯定大于最小桶容量),这样再次缩小查找的范围,继续循环直到终止,终止时,当前的桶容量既是最小的桶容量。

#include<iostream>
using namespace std;

int getMax(int A[], int n)
{
	int max = -1;
	for (int i = 0; i < n; i++)
	{
		if (A[i]>max)
			max = A[i];
	}
	return max;
}
int getSum(int A[], int n)
{
	int sum = 0;
	for (int i = 0; i < n; i++)
	{
		sum += A[i];
	}
	return sum;
}

int getRequiredNum(int A[], int n, int MaxPer)
{
	int num_bucket = 1;     //至少需要一个桶
	int sum = 0;
	for (int i = 0; i < n; i++)
	{
		sum += A[i];
		if (sum>MaxPer)     //超出桶容量
		{
			sum = A[i];
			num_bucket++;
		}
	}
	return num_bucket;
}

int BinarySearch(int A[], int n, int k)
{
	int low = getMax(A, n);
	int high = getSum(A, n);

	while (low<high)    //找到桶容量的范围
	{
		int mid = (low + high) / 2;
		int result = getRequiredNum(A, n, mid);
		if (result > k)   //所需桶数量大于实际有的,需要增加容量
		{
			low = mid + 1;
		}
		else          //result<=k,尝试减小容量
		{
			high = mid;
		}
	}
	return low;
}

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Python中,数组分段映射可以通过数组切片来实现。数组切片是指通过指定起始索引和结束索引来获取数组的一部分。在切片中,可以使用冒号(:)来表示范围。例如,a\[1:3\]表示获取数组a中索引为1到2的元素(不包括索引为3的元素)。\[2\] 另外,在numpy库中,可以使用整数数组索引、布尔索引和花式索引等方式进行复杂的数组切片操作。整数数组索引是指使用一个整数数组来指定要获取的元素的索引位置。布尔索引是指使用一个布尔数组来选择满足条件的元素。花式索引是指使用一个整数数组来指定要获取的元素的索引位置,可以实现非连续的切片操作。\[1\] 综上所述,Python中的数组分段映射可以通过数组切片、整数数组索引、布尔索引和花式索引等方式来实现。具体的使用方法可以根据具体的需求选择合适的方式进行操作。 #### 引用[.reference_title] - *1* *2* [Python中数组切片的用法详解](https://blog.csdn.net/weixin_42782150/article/details/127014616)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [python分段函数](https://blog.csdn.net/weixin_39630466/article/details/109924654)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值