LeetCode/特别的排列

给你一个下标从 0 开始的整数数组 nums ,它包含 n 个 互不相同 的正整数。如果 nums 的一个排列满足以下条件,我们称它是一个特别的排列:
对于 0 <= i < n - 1 的下标 i ,要么 nums[i] % nums[i+1] == 0 ,要么 nums[i+1] % nums[i] == 0

1. 记忆化搜索 + 状态压缩

class Solution {
public:
    int specialPerm(vector<int>& nums) {
        int mod = 1e9+7;
        int m = nums.size();
        int memo[m][m<<14];
        memset(memo, -1, sizeof(memo));
        function<int(int, int,int)> f = [&](int pre, int mask,int depth) -> int {
            if (depth==m) //边界条件一
                return 1;
            if (pre!=-1&&memo[pre][mask] != -1) //已经存储过,直接剪枝返回
                return memo[pre][mask];
            int res = 0; //计算无重复数字
            
            //做选择
            for (int j = 0; j < nums.size(); j++) //遍历数做选择
                if ((mask & 1<<j) == 0){ // j 不在 mask 中
                        if(pre==-1||nums[pre]%nums[j]==0||nums[j]%nums[pre]==0)
                            res = (res + f(j, mask | (1 << j),depth+1)%mod)%mod;
                }
            if(pre!=-1)
                memo[pre][mask] = res%mod;
            return res;
        };
        
        return f(-1, 0,0);   //从下标-1开始,初始状态为空,
    }
};
posted @ 2023-06-23 20:06  失控D大白兔  阅读(23)  评论(0编辑  收藏  举报