暴力出所有的可能集合,再与要求的限制作比较。最终求出能组成的新集合数量。
有n个元素,每个元素都有取与不取的两种可能,所以应该是2^n个.
因为n<=20,故至多有10^6个集合,我们可以采用暴力搜索。
因为要遍历出所有的取值情况,我们使用回溯来解决此类问题。回溯类型的题目有一套通用的模板。
回溯法
result = [] dfs backtrack(路径,选择列表): if(满足结束条件): result.add(路径) return 做选择 backtrack(路径,选择列表) 撤销选择 backtrack(路径,选择列表)
参考代码
import java.util.*; /* * public class Point { * int x; * int y; * } */ public class Solution { /** * 返回新集合的种类数 * @param n int整型 集合大小 * @param m int整型 限制数量 * @param limit Point类一维数组 不能同时出现的(u,v)集合 * @return int整型 */ int res = 0; boolean[] v; public void dfs(Point[] limit,int x,int n){ if(x>n){ for(Point lim : limit) if(v[lim.x]&& v[lim.y]) return; res++; return; } v[x] = true; dfs(limit,x+1,n); v[x] = false; dfs(limit,x+1,n); } public int solve(int n, int m, Point[] limit){ v = new boolean[n+1]; dfs(limit,1,n); return res; } }