zoukankan      html  css  js  c++  java
  • 和谐分组的题解

    班共有名学生,按照学号从的顺序每名学生的身高分别为。
    由于是新学期,班需要进行分组,分组的要求如下:

    1. 进行分组的组数不能超过。
    2. 每组的人的学号必须相邻。

    由于身高差过大的人分在同一个组会激起组内内部矛盾(QAQ),所以我们定义一个分组方案的不和谐度为每个组的身高极差(最高的身高-最矮的身高)的最大值。
    我们希望最小化这个不和谐度,输出这个不和谐度。

    讲解二分

    终于是正常一点的题目了,并且是我最喜欢的算法(蒟蒻最喜欢的算法是并查集、二分、dp、LCA)

    二分是确定一个答案然后对其分析,而答案常常有这样一种情况:

    左闭右开

    ​ 左闭右开

    ​ 右闭左开

    题目通常会让我们找符合条件的最大值或最小值。

    以这道题为例,就是去在可能的谐度度中找一个最小的。

    比答案大的都可以,不答案小的都不可以。

    这个我们叫右闭左开。

    而比答案小的都可以,不答案大的都不可以。

    这个我们叫左闭右开。

    二分顾名思义,就是二分。

    左闭右开:

    int l=0,r=INT_MAX/2;
    while(l+1<r){
    	int mid=(l+r)>>1;
    	if(check(mid))l=mid;//这里不同
    	else r=mid;//这里不同
    }
    

    右闭左开:

    int l=0,r=INT_MAX/2;
    while(l+1<r){
    	int mid=(l+r)>>1;
    	if(check(mid))r=mid;//这里不同
    	else l=mid;//这里不同
    }
    

    分析

    现在我们已经会了二分,我们可以愉快地做这道题了。

    我们可以开始写 checkcheck 函数:

    bool check(int x){//check函数顾名思义,就是用来反对我们的答案x是否可行
    	int maxn=a[1],minn=a[1],s=1;//初始化
    	for(int i=2;i<=n;i++){
    		maxn=max(maxn,a[i]);//最大
    		minn=min(minn,a[i]);//最小
    		if(maxn-minn>x){
    			s++;//新分一个组
    			maxn=a[i];//初始化
    			minn=a[i];//初始化
    		}
    	}
    	return s<=k;//如果组数小于等于k,就说明不可行
    }
    

    总代码

    #include <bits/stdc++.h>
    using namespace std;
    template<typename T>inline void read(T &FF){
        T RR=1;FF=0;char CH=getchar();
        for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
        for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
        FF*=RR;
    }
    template<typename T>void write(T x){
        if(x<0)putchar('-'),x*=-1;
        if(x>9)write(x/10);
        putchar(x%10+48);
    }
    const int MAXN=1e5+10;
    int n,k,a[MAXN];
    bool check(int x){
        int maxn=a[1],minn=a[1],s=1;
        for(int i=2;i<=n;i++){
            maxn=max(maxn,a[i]);
            minn=min(minn,a[i]);
            if(maxn-minn>x){
                s++;
                maxn=a[i];
                minn=a[i];
            }
        }
        return s<=k;
    }
    int main(){
        read(n);read(k);
        for(int i=1;i<=n;i++)read(a[i]);
        int l=0,r=INT_MAX/2;
        while(l+1<r){
            int mid=(l+r)>>1;
            if(check(mid))r=mid;
            else l=mid;
        }write(r);
        return 0;
    }
    
  • 相关阅读:
    Schema和数据类型优化?
    语雀发布博客园
    为知笔记文章目录
    码云搭建博客
    springboot的过滤器、监听器、拦截器
    springboot常用注解
    springboot使用小技巧合集
    springboot整合swagger2
    强制卸载win软件
    xshell下载和优化配置
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/12816943.html
Copyright © 2011-2022 走看看