NC204418 新集合
题目
题目描述
集合 中有整数 到 ,牛牛想从中挑几个整数组成一个新的集合。
现在牛妹给牛牛加了 个限制 ,每个限制包含两个整数 和 ( ),且 和 不能同时出现在新集合中 。
请问牛牛能组成的新集合多少种。
可以选 0 个数。
返回一个整数,即新集合的种类数。
示例1
输入
3,2,[(1,2),(2,3)]
返回值
5
说明
当 n = 3 时,共有 8 个子集,当加上限制 (1, 2), (2, 3) 后,合法的自己有 共 5 个
备注
第一个参数为 。第二个参数为 。第三个参数为 对 (u, v) 。
题解
知识点:DFS。
一道计数题,用dfs比较合适。
有两种枚举方式:
-
dfs的第 层枚举集合中第 个放的数字,如果能放立刻加一,为了保证不重复,我们每次都放比上一次大的数。
-
dfs第 层枚举第 个数字”放“和“不放“进集合,每次能放的时候选择放可以加一,选择不放则不加。
两者dfs的区别在于,前者每次都放一个新的数字,一定能确定一个新的状态,没有搜索节点是被浪费的;后者因为只有对某个数字选择”放“的时候才会确定一个新状态,而选择“不放”则继承上一层状态不能确定一个新的状态,需要枚举完 个数字才能遍历所有可能状态。显然,前者的复杂度更优秀。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; struct Point { int x, y; }; int cnt; bool vis[27]; void dfs(int n, vector<Point> &limit, int pos = 0) { for (int i = pos + 1;i <= n;i++) { bool ok = true; for (int j = 0;j < limit.size();j++) { if (limit[j].x == i && vis[limit[j].y]) ok &= false; if (limit[j].y == i && vis[limit[j].x]) ok &= false; } if (ok) { cnt++; vis[i] = 1; dfs(n, limit, i); vis[i] = 0; } } } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n, m; cin >> n >> m; vector<Point> limit; for (int i = 0;i < m;i++) { int u, v; cin >> u >> v; limit.push_back({ u,v }); } dfs(n, limit); cout << cnt + 1 << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16482857.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧