1436:数列分段II -整型二分

1436:数列分段II

题目来源:一本通


【输入样例】

cpp 复制代码
5 3
4 2 4 5 1

【输出样例】

cpp 复制代码
6

题意

将数列分成若干段,最多M段,求这些段中最大值中的最小值。(M<=N是M的约束)

思路

  • 最大最小问题考虑二分。由于M越大,则每段的平均值越小,即里面的最大值的越小。M作为约束,所以当分段>M作为check()函数跳出条件
  • 题目没给数据范围,所以二分区间可以选择min(a\[i),max(sum(ai)](当然,简单点就直接设0,1e10,不会超时),而M作为约束条件

数据约束

注意事项

哈哈,总有一个样例过不了。检查一下代码,发现有漏洞,始终要清醒:t必须是当前子段和最大值,但当ai>t,sum=ai 然后进入下一个循环,所以就有Bug。因此需要单独判断ai,如果>t 就不符合条件。

eg:4 1 4 5 2 很显然有数据5,当Mid=4就不可能成立

参考代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N =1000000; 
int n,m,a[N];
bool check(int t);//判断是否有m段 
int main()
{
	cin>>n>>m;
	int l = 0, r = 0;
	for(int i=0;i<n;i++){
		cin>>a[i];
		l = min(l,a[i]) ;
		r += a[i];
	}
	//二分
	int anwser = 0;
	while(l<=r){
		int mid = (r+l)/2;
		if(check(mid)) {
			anwser = mid;
			r= mid-1; //必须要区间保证是收敛的(不断缩小的) 
		}
		else l = mid+1;
	} 
	cout<<anwser;
   return 0;
}
bool check(int t){
	int sum = 0,ans = 1;//默认为a[0]容易有Bug 万一a[0]>m那就凉凉 
	for(int i=0;i<n;i++){
		if(a[i]>t){ //段里面的单个数据不能超过t否则出错 
			return false;
		}
		sum += a[i];
//		if(t ==5 ) cout<<sum<<"/"<<i<<"   "<<ans<<endl;
		//判断ans的情况,因为ans比m大,说明t可以分更小 ,也就是字段和不是最小值 
		if(sum>t){
			//因为t是sum里面的最大值,所以必须保证sum<=t 
			sum = a[i];
			ans++;
		}
		if(ans>m){
		   return false;
		}
	}
	return true;
}
相关推荐
洋不写bug34 分钟前
排序(一)基础排序,插入|希尔|冒泡|直接选择排序详解
java·算法·排序算法·插入排序·冒泡排序·希尔排序·直接选择排序
牧羊人.33335 分钟前
动手学深度学习 03 | 卷积神经网络实现手写数字识别
人工智能·深度学习·神经网络·算法·cnn
AgentMaster1 小时前
数据治理工具选型指南:一套可复用的四阶段决策框架
大数据·数据结构·人工智能·算法
程序猿编码1 小时前
纯C++轻量计算机视觉推理引擎:基于GGML的端侧CV模型部署技术全解析
开发语言·c++·计算机视觉·大模型·transformer
liliangcsdn1 小时前
最终留出样本/样本外测试集-holdout解读
算法
爱敲代码的小黄2 小时前
机器学习入门:从数据、训练到业务决策
算法
数据知道2 小时前
哈希与密码存储——bcrypt、Argon2、盐值与彩虹表
网络·算法·安全·网络安全·密码学·哈希算法
haon11222 小时前
树模型在信贷风控怎么用——从决策树到 XGBoost
大数据·人工智能·算法·决策树·机器学习·数据挖掘
wordbaby2 小时前
BM25 是什么?手把手拆解搜索引擎的核心算法
人工智能·算法