[朝花夕拾] LeetCode刷题合辑
作者:互联网
20220228 1601. 最多可达成的换楼请求数目
题目链接:https://leetcode-cn.com/problems/maximum-number-of-achievable-transfer-requests/
方法一:DFS 枚举
枚举所有换楼请求的选择与不选择两种情况,最后判断是否满足题意,时间复杂度为 O(2 ^ m),m 为请求个数,依题意 m <= 16,符合要求。
1 #include <cstring> 2 3 const int N = 25; 4 5 class Solution { 6 public: 7 int a[N][N], b[N]; 8 int dfs(int o, int x, int n, int m) { 9 int res = 0; 10 if (o == m) { 11 int tot = 0; 12 for (int i = 0; i < n; i++) { 13 for (int j = 0; j < m; j++) 14 tot += (b[j] ? a[j][i] : 0); 15 if (tot != 0) return 0; 16 } 17 return x; 18 } 19 b[o] = 1; 20 res = dfs(o + 1, x + 1, n, m); 21 b[o] = 0; 22 res = max(res, dfs(o + 1, x, n, m)); 23 return res; 24 } 25 int maximumRequests(int n, vector<vector<int>>& requests) { 26 int m = requests.size(); 27 for (int i = 0; i < m; i++) 28 a[i][requests[i][0]] += -1, a[i][requests[i][1]] += 1; 29 memset(b, 0, sizeof(b)); 30 return dfs(0, 0, n, m); 31 } 32 };
其实不用转换为二维数组,可以节省空间,并且 DFS 过程中就可以维护是否满足条件而不需要最后用 for 循环判断,代码有优化空间。
方法二:二进制位运算枚举
由于对于请求只有选择与不选择两种可能,使用二进制位运算,会大幅精简代码,但需要再最后用 for 循环判断是否满足条件,故时间复杂度会达到 O(n * 2 ^ m)。
1 const int N = 25; 2 3 class Solution { 4 public: 5 int maximumRequests(int n, vector<vector<int>>& r) { 6 int a[N], m = r.size(), ans = 0; 7 for (int o = 0; o < (1 << m); o++) { 8 memset(a, 0, sizeof(a)); 9 int res = 0; 10 for (int i = 0; i < m; i++) 11 if (o & (1 << i)) 12 a[r[i][0]]--, a[r[i][1]]++, res++; 13 int tot = 0; 14 for (int i = 0; i < n; i++) 15 tot += (a[i] == 0); 16 if (tot == n) ans = max(res, ans); 17 } 18 return ans; 19 } 20 };
其他:最小费用最大流
由于数据量并不大,用网络流有点杀鸡用牛刀了。
标签:25,return,int,res,合辑,dfs,requests,LeetCode,刷题 来源: https://www.cnblogs.com/jinkun113/p/15945270.html