题意
在1-n中选出任意个数(可以是0个数)组成新的集合,但要满足m个限制条件。每个条件(u,v)限制u,v两个数不能同时在新的集合中。
解法
我们观察到 ,而每个数有选与不选两种状态,所以总状态数为
。
对于我们来说是一个可以接受的状态数,也就是说在
的数据范围内,
的复杂度是可以接受的,我们可以暴力搜索完成这道题。
那么剩下来的就很简单的。我们只需要依次从1到n枚举每个数是否可以选中(与题目给出的限制条件对比),如果可以选中,答案就加上选中后的数目。最后答案再加上不选当前这个数的结果。
我们可以使用long long二进制状态压缩储存状态。(因为long long类型的大小很小,可以很方便的在调用的时候传递。当然也可以使用全局数组,只要记得还原就行) (在每次插入前判断是否矛盾)
/**
* struct Point {
* int x;
* int y;
* Point(int xx, int yy) : x(xx), y(yy) {}
* };
*/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int 集合大小
* @param m int 限制数量
* @param limit Pointvector 不能同时出现的(u,v)集合
* @return int
*/
int solve(int n, int m, vector<Point>& limit) {
// 判断能不能选
return dfs(n,1,0,limit);
}
int dfs (int n,int num,long long state,vector<Point>& limit) {
if (num == n + 1) return 1;
bool can = true;
for (auto &p:limit) {
if(p.x == num) {
if ((state >> p.y) & 1) {
can = false;
break;
}
}
if(p.y == num) {
if ((state >> p.x) & 1) {
can = false;
break;
}
}
}
int ret = 0;
if (can) {
ret += dfs (n,num + 1,state | (1 << num),limit);
}
ret += dfs (n,num + 1,state,limit);
return ret;
}
};
京公网安备 11010502036488号