状态压缩+动态规划
原理如下:
遍历位图可以得到所有组合序列,将这些序列的每一位看作一个数,取序列中1总量的值作为每轮遍历的位,此时对每个这样的位都能和所有数进行匹配,因为一开始就取的是全排列,并且我们不需要考虑其它位的排列状况,这一位能换的话就加上这一位不能换的总量,这样一来通过整个遍历过程就可以得到排列总数。
class Solution {
public:
int countArrangement(int n) {
vector<int>tmp(1<<n);
tmp[0]=1;
for(int mask=1;mask<(1<<n);mask++){
int m=__builtin_popcount(mask);
for(int i=0;i<n;i++){
if(mask&(1<<i)&&(m%(i+1)==0||(i+1)%m==0)) tmp[mask]+=tmp[mask^(1<<i)];
}
}
return tmp[(1<<n)-1];
}
};