【算法】记忆化回溯+状态压缩+分治

// 优化四:指令集优化,让CPU使用POPCNT指令,从而加速__builtin_popcount
#pragma GCC target ("sse4.2")
__builtin_popcount(state) == sz;   该指令计算state中二进制1的个数

5619. 最小不兼容性

给你一个整数数组 nums 和一个整数 k 。你需要将这个数组划分到 k 个相同大小的子集中,使得同一个子集里面没有两个相同的元素。
一个子集的 不兼容性 是该子集里面最大值和最小值的差。
请你返回将数组分成 k 个子集后,各子集 不兼容性 的 和 的 最小值 ,如果无法分成分成 k 个子集,返回 -1 。
子集的定义是数组中一些数字的集合,对数字顺序没有要求。

  • 1 <= k <= nums.length <= 16
  • nums.length 能被 k 整除。
  • 1 <= nums[i] <= nums.length

思路

  • N有限定范围,即 N ∈ [ 1 , 16 ] N \in [1,16] N[1,16],显然可以使用状态压缩来表示数组所有的子集(状态),总状态数为 2 N 2^N 2N.递归求解每个状态数所对应的最小不兼容性,最后可得总集即状态数为 2 N − 1 2^N-1 2N1状态数的最小不兼容性。

在枚举分组方案时,若朴素的递归 [ 1... s t a t e ] [1...state] [1...state],总复杂度

  • 采用分治,即 r e t ( n u m s ) = m i n ( ( r e t ( l e f t 1 ) + r e t ( r i g h t
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值