CF883I Photo Processing题解(二分+DP)

2 篇文章 0 订阅
本文介绍了一种通过二分查找和动态规划解决的照片分组问题算法。该算法旨在将一组具有不同对比度的照片按特定条件最优地分成多个组,确保每组至少包含k张照片且组内对比度差异最小。
摘要由CSDN通过智能技术生成

题目描述

Evlampiy has found one more cool application to process photos. However the application has certain limitations.
Each photo i has a contrast vi. In order for the processing to be truly of high quality, the application must receive at least k photos with contrasts which differ as little as possible.
Evlampiy already knows the contrast vi for each of his n photos. Now he wants to split the photos into groups, so that each group contains at least k photos. As a result, each photo must belong to exactly one group.
He considers a processing time of the j-th group to be the difference between the maximum and minimum values of vi in the group. Because of multithreading the processing time of a division into groups is the maximum processing time among all groups.
Split n photos into groups in a such way that the processing time of the division is the minimum possible, i.e. that the the maximum processing time over all groups as least as possible.

输入

The first line contains two integers n and k (1 ≤ k ≤ n ≤ 3·105) — number of photos and minimum size of a group.
The second line contains n integers v1, v2, …, vn (1 ≤ vi ≤ 109), where vi is the contrast of the i-th photo.

输出

Print the minimal processing time of the division into groups.

样例输入1

5 2
50 110 130 40 120

样例输出1

20

样例输入2

4 1
2 3 4 1

样例输出2

0

题目大意为给定一组数,要求将其分成若干组,使其满足:每一组的元素个数大于等于k且每一组中元素的最大值与最小值之差尽可能小,并求出所有组中这个差值的最大值最小的情况。
首先,看到关键字最大值最小,可以考虑二分答案,那么问题的关键在于判断二分结果的正确性。一开始我是采用贪心的策略,将原数列升序排序之后从左往右扫一遍,遇到能够合并成一组的就合并,但这题加了一个元素数量大于等于k的限制,若只是单纯地扫一遍,可能会出现最后一组元素数量小于k的情况而无法处理。
因此,这里采用DP的方法。先将原数列升序排序,用一个数组f[i]表示前i个数字能否分成满足条件的若干组,假设当前二分结果是mid,我们转移f[i],因为元素最值之差要小于等于mid,我们从最前面开始往后查找,找到第一个a[j]使得a[i]-a[j]<=mid,这个j设为左边界l,因为同一个组中的元素个数要大于等于k,所以我们设置右边界r=i-k+1,那么以区间[l,r]内的任意元素a[j]为起点,a[i]为终点,区间[j,i]内的所有元素都可以分为满足条件的一组,那么只要满足f[j-1]=1即前j-1个元素可以分成满足条件的若干组,f[i]即为1。
即转移方程为f[i]=∪f[j-1] (j∈[l,r])。最后只要判断f[n]是否为1即可。总体时间复杂度约为O(nlogn)。

#include<bits/stdc++.h>
#define ll long long
#define next next_
#define y1 yy
using namespace std;
int n,k,a[300010],ans,f[300010];
bool ok(int t){
	for(int i=1;i<=n;i++) f[i]=0;
	f[0]=1;
	int l=1,r;
	for(int i=1;i<=n;i++){
		while(a[i]-a[l]>t) l++;
		r=i-k+1;
		for(int j=l;j<=r;j++) if(f[j-1]){
			f[i]=1;
			break;
		}
		else l++;
	}
	return f[n];
}
int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	sort(a+1,a+1+n);
	int l=0,r=a[n];
	while(l<=r){
		int mid=l+r>>1;
		if(ok(mid)){
			ans=mid;
			r=mid-1;
		}
		else l=mid+1;
		
	}
	printf("%d",ans);
	return 0;
}
【资源介绍】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,也可以作为小白实战演练和初期项目立项演示的重要参考借鉴资料。 3、本资源作为“学习资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研和多多调试实践。 图像数据处理工具+数据(帮助用户快速划分数据集并增强图像数据集。通过自动化数据处理流程,简化了深度学习项目的数据准备工作).zip 图像数据处理工具+数据(帮助用户快速划分数据集并增强图像数据集。通过自动化数据处理流程,简化了深度学习项目的数据准备工作).zip 图像数据处理工具+数据(帮助用户快速划分数据集并增强图像数据集。通过自动化数据处理流程,简化了深度学习项目的数据准备工作).zip 图像数据处理工具+数据(帮助用户快速划分数据集并增强图像数据集。通过自动化数据处理流程,简化了深度学习项目的数据准备工作).zip 图像数据处理工具+数据(帮助用户快速划分数据集并增强图像数据集。通过自动化数据处理流程,简化了深度学习项目的数据准备工作).zip 图像数据处理工具+数据(帮助用户快速划分数据集并增强图像数据集。通过自动化数据处理流程,简化了深度学习项目的数据准备工作).zip 图像数据处理工具+数据(帮助用户快速划分数据集并增强图像数据集。通过自动化数据处理流程,简化了深度学习项目的数据准备工作).zip 图像数据处理工具+数据(帮助用户快速划分数据集并增强图像数据集。通过自动化数据处理流程,简化了深度学习项目的数据准备工作).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值