【算法】Minimum Incompatibility 最小不兼容性 DFS

news/2024/11/8 12:15:10/

文章目录

  • Minimum Incompatibility 最小不兼容性
    • 问题描述:
    • 分析
    • 代码
    • Tag

Minimum Incompatibility 最小不兼容性

问题描述:

给你一个整数数组 nums 和一个整数 k 。你需要将这个数组划分到 k 个相同大小的子集中,使得同一个子集里面没有两个相同的元素。

一个子集的 不兼容性 是该子集里面最大值和最小值的差。

请你返回将数组分成 k 个子集后,各子集 不兼容性 的 和 的 最小值 ,如果无法分成分成 k 个子集,返回 -1 。

子集的定义是数组中一些数字的集合,对数字顺序没有要求。

k , n u m s . l e n g t h 范围 [ 1 , 16 ] , n u m s . l e n g t h m o d k = = 0 , n u m s [ i ] 范围 [ 1 , n u m s . l e n g t h ] k ,nums.length 范围[1,16 ] ,nums.length\mod k==0 ,nums[i] 范围[1,nums.length ] k,nums.length范围[1,16],nums.lengthmodk==0,nums[i]范围[1,nums.length]

分析

< E m p t y M a t h B l o c k > <Empty \space Math \space Block> <Empty Math Block>

问题要求把整数数组 n u m s nums nums n n n个元素平均分成 k k k个组,而每个组就会有 n / k n/k n/k个元素。

与此同时,根据题目,每个组会有一个 i n c o m p a t i b i l i t y incompatibility incompatibility值,把 k k k个组的 i n c o m p a t i b i l i t y incompatibility incompatibility值累加得到 s u m sum sum,要求找到最小的 s u m sum sum。问题大概就是这么个意思。

i n c o m p a t i b i l i t y incompatibility incompatibility的值是由这一个组的 m a x − m i n max-min maxmin产生的。同时有限制不允许一个组有重复的元素。

所以理论上 i n c o m p a t i b i l i t y > 0 incompatibility>0 incompatibility>0

首先很容易根据条件判断出哪种情况是不可能得到sum的。即 n u m s nums nums中的某个元素次数 c n t [ i ] > k cnt[i]>k cnt[i]>k,这样就无法满足组内元素不重复

贪心策略?

到此就可以开始找了,朴素的想法,既然要最小,那么就让每个组最小这样就可以得到整体的最小。
那么第一步就是先排序,这样相邻的元素就会靠近,把相邻的满足条件的元素划分到一个组中,这样就可以得到最小了。
想法很好,但是并不能保证最终的结果是最小的。

也就是说简单的贪心策略并不能完全保证该策略的最终结果是最小的。

剩下的就只有暴力了, m = n / k m=n/k m=n/k, m m m为子集的大小,n最大可取 16 16 16,所以 n n n的所有非空子集数量就是 2 16 − 1 2^{16}-1 2161 ,即65535。
所以通过条件筛选出所有符合题意的子集。

  • 满足 子集大小size==m,
  • 满足 子集中不能有重复数字元素。

同时还可以将子集的 i n c o m p a t i b i l i t y incompatibility incompatibility值计算出来。
到此每个子集都是符合条件的,剩下的就是把从X个子集中选出k个,并且他们的并集== 2 16 − 1 2^{16}-1 2161

d f s ( s t a t e ) = min ⁡ s u b ∈ U ∖ s t a t e d f s ( s t a t e ⊕ s u b ) + m a p [ s u b ] dfs(state) = \min_{sub\in {U\setminus state} } {dfs(state\oplus sub)+map[sub]} \\ dfs(state)=subUstatemindfs(statesub)+map[sub]

代码

class Solution {int[] memo,map;int INF = 1<<30,u=0;public int minimumIncompatibility(int[] nums, int k) {int n = nums.length,max = 0;int[] cnt = new int[n+1];for(int num: nums){cnt[num]++;if(max<cnt[num]) max=cnt[num];if(max>k) return -1;}Arrays.sort(nums);memo = new int[1<<n];int m = n/k,state = 1;u = (1<<n)-1;map = new int[1<<n];for(;state<=u;state++){map[state] = memo[state] = -1;if(Integer.bitCount(state)!=m) continue; int curmin=16,curmax = 0,pre=-1;boolean dup =false;for(int i = 0;i<n;i++){if((state&(1<<i))==0) continue;if(pre==nums[i]){dup = true;break;}pre = nums[i];curmin= Math.min(curmin,nums[i]);curmax= Math.max(curmax,nums[i]);}if(dup) continue;map[state] = curmax-curmin;}return dfs(u);}public int dfs(int state){ if(state==0) return 0;if(memo[state]!=-1) return memo[state];int res = INF;for(int sub =state;sub>0;sub =(sub-1)&state){if(map[sub]==-1) continue; int nx = state^sub; int t = dfs(nx);res = Math.min(res,map[sub]+t);}        return memo[state]=res;}
}

时间复杂度 O ( 3 n ) O( 3^ n) O(3n)

空间复杂度 O ( 2 n ) O(2^n) O(2n)

Tag

Memoization
Bit Manipulation
Dynamic Programming
Bitmask


http://www.ppmy.cn/news/634321.html

相关文章

thinkpad x1 carbon 5th 2017 ubuntu20.04安装指纹登录

操作完整记录 为解决指纹识别问题&#xff0c;这几年先后尝试了网上不少方法&#xff0c;最近终于有所突破了&#xff08;安全性未知&#xff09;。 当前环境&#xff1a;Ubuntu 20.04&#xff0c;GNOME 3.36.8 一点点准备工作&#xff1a; 通过lsusb检测到指纹识别设备&am…

lenovo thinkpad x1 carbon 无法打开bios解决方法

项目场景&#xff1a; 安装linux过程中需要设置figuration&#xff0c;但是尝试了很多种方法都打不开bios&#xff0c;这里记录解决方法。 解决方案&#xff1a; 正常关机再打开电脑一直按f1&#xff0c;这种正常方法不行尝试一下按fnfnlock之后&#xff0c;再关机再开&#…

carbon安装win7 thinkpad x1_联想ThinkPad X1 Carbon 2018笔记本如何安装win7系统

联想ThinkPad X1 Carbon 2018采用了碳纤维材质&#xff0c;韧性更强、保证坚固的同时&#xff0c;进一步降低了整机重量&#xff0c;更加便携。那这么一款电脑要怎么安装win10系统呢?下面就让我们一起来看看联想ThinkPad X1 Carbon 2018安装win7系统的操作方法。 安装方法&…

x1 carbon 扩展屏 模糊

x1 carbon 扩展屏 模糊&#xff0c;扩展屏是dell的屏&#xff0c;分辨率最大是1920*1080, x1最大是2560*1440. 不论是通过DP mini转VGA&#xff0c;还是HDMI&#xff0c;输出都是模糊&#xff0c;只有复制屏幕的时候看起来还稍微好点。 找了几圈终于找到了解决方案&#xff0c;…

carbon安装win7 thinkpad x1_联想thinkpad x1 carbon 2017笔记本使用u启动u盘安装win7系统教程...

联想thinkpad x1 carbon 2017笔记本是一款2017年上市的商务办公笔记本电脑&#xff0c;这款电脑搭载了英特尔酷睿第七代i7处理器以及性能级核心显卡&#xff0c;能够满足用户们日常办公使用需求&#xff0c;那么联想thinkpad x1 carbon 2017笔记本怎么使用u启动u盘安装win7系统…

ThinkPad X1 Carbon 安装Ubuntu 18.04到移动硬盘 教程指南

ThinkPad X1 Carbon 安装Ubuntu 18.04到移动硬盘 教程指南 安装准备步骤下载ubuntu制作启动盘关闭Win系统快速启动设置移动硬盘设置BIOS安全启动设置启动顺序设置 安装ubuntu到硬盘Ubuntu 界面安装安装引导步骤安装启动引导的设备 写在前头&#xff1a; 因为在自学CMU的CSAPP课…

linux下thinkpad X1 carbon 2018 电源管理

需要描述 1、 thinkpad x1 carbon电脑安装linux系统、Ubuntu 20.04&#xff0c;估计其他linux系统也一样 2、想实现类似windows下电池超过阈值停止充电、低于阈值开始充电功能&#xff0c;提高电池利用率。 步骤&#xff1a; 1、从github上下载tpacpi-bat源代码https://gith…

carbon安装win7 thinkpad x1_联想ThinkPad X1 Carbon 2016 u盘pe如何重装win7系统

联想ThinkPad X1 Carbon 2016是一款14英寸商务办公本&#xff0c;搭载了Intel 酷睿i5 6200U处理器、8GB LPDDR3 1866MHz运行内存。而电脑最大内存容量为16GB&#xff0c;再加上192GB SSD固态硬盘&#xff0c;性能十分稳定。但是&#xff0c;大家对于这款电脑的系统重装是否了解…