第一部分 基础算法(第三章 二分算法)例题

博客探讨了如何使用二分算法解决三种不同类型的题目:奶牛晒衣服问题涉及分段和的最大值最小化,防具布置问题要求找出防线上的破绽位置,最大均值问题需要找到序列中平均值最大的连续子段。通过案例分析和解题思路,阐述了二分算法在处理这些问题时的作用和应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

例题一 奶牛晒衣服:link

题目描述
对于给定的一个长度为 n 的正整数数列 ,现在将其分成 m 段,并要求每段连续,且每段和的最大值最小。

输入格式
第 1 行包含两个正整数 。
第 2 行包含 i 个空格隔开的非负整数 a i a_i ai

输出格式
仅包含一个正整数,即每段和最大值最小为多少。

样例
样例输入

5 3
4 2 4 5 1

样例输出

6

数据范围与提示
对于 20% 的数据,n<=5。
对于 50% 的数据,n<=1000。
对于 100% 的数据, 1 < = m , n < = 1 0 5 1<=m,n<=10^5 1<=m,n<=105 a i a_i ai 之和不超过 1 0 9 10^9 109

思路:
此题出现了一个“最大值最小”的字眼,这种就是单调性最常见的特征之一。(摘自教材上)
简单来说,对于这一种题目,我们关心数据值域,
如果太大了,直接考虑用二分。
设x为最大值的最小值,即每一段都要<=x,
那我们寻找一个x满足分段的个数不超过m,
然后将满足条件的所有值中取一个min就是最优解。

#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int n, m, a[N];
bool check(int x)
{
   
   
	int ans = 1, tot = 0;
	for(int i = 1; i <= n; i++)
	{
   
   
		if(tot + a[i] > x) 
		{
   
   
			ans++, tot = a[i];
			if(a[i]>x) return 0;
		}
		else tot += a[i];
	}
	return ans <= m; 
}
int main()
{
   
   
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i++) scanf
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值