给定一个长度为n的数组,找到子集的数量,其中子集的XOR等于给定数量
Given an array of length n, find number of subsets where XOR of a subset is equal to a given number
给定一个长度为n
的数组arr
,求出arr
有多少个子集,使得这些子集的XOR(^)
等于给定的数ans
。
我有这种dp
方法,但有没有办法提高它的时间复杂性。CCD_ 7总是小于1024。
这里ans
是编号,使得子集的XOR(^)
等于它。arr[n]
包含所有数字
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for(i = 1; i <= n; i++){
for(j = 0; j < 1024; j++) {
dp[i][j] = (dp[i-1][j] + dp[i-1][j^arr[i]]);
}
}
cout << (dp[n][ans]);
来自用户3386109的评论,构建在您的代码之上:
/* Warning: Untested */
int counts[1024] = {0}, ways[1024];
for(int i = 1; i <= n; ++i) counts[ arr[i] ] += 1;
for(int i = 0; i <= 1024; ++i) {
const int z = counts[i];
// Look for overflow here
ways[i] = z == 0 ?
0 :
(int)(1U << (z-1));
}
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for(i = 1; i <= 1024; i++){
for(j = 0; j < 1024; j++) {
// Check for overflow
const int howmany = ways[i] * dp[i-1][j];
dp[i][j] += howmany;
dp[i][j^i] += howmany;
}
}
cout << (dp[1024][ans]);
为了计算odd_
和even_
,您还可以使用以下方法:
nc0+nc2+=nc1+nc3=2n-1
因为选择奇数项目的方式数=拒绝奇数项目的方法数=选择偶数的方式数
您还可以通过只保留2列dp数组并在丢弃dp[i-2][x]
时重用它们来优化空间。
动态编程背后的理念是,(1)永远不要计算两次相同的结果,(2)只根据需要计算结果,而不是在执行时预先计算整个结果。
因此,solve(arr, n, ans)
与ans < 1024
、n < 1000000
和arr = array[n]
需要一个解。使dp[n][ans]
保持结果数量的想法是合理的,因此需要将dp大小作为dp = array[n+1][1024]
。我们需要的是一种方法来区分尚未计算的结果和可用的结果。所以memset(dp, -1, sizeof(dp))
,然后就像你已经做了dp[0][0] = 1
一样
solve(arr, n, ans):
if (dp[n][ans] == -1)
if (n == 0) // and ans != 0 since that was initialized already
dp[n][ans] = 0
else
// combine results with current and without current array element
dp[n][ans] = solve(arr + 1, n - 1, ans) + solve(arr + 1, n - 1, ans XOR arr[0])
return dp[n][ans]
优点是,在找到解决方案的过程中,dp
数组只进行了部分计算,因此这可能会节省一些时间。
根据堆栈大小和n
,可能需要将其从递归转换为迭代解决方案
相关文章:
- 我的神经网络不起作用 [XOR 问题]
- 给定一个向量,如何找到该向量的所有子集和的原始索引
- 在子集化后将包含索引号的列表列表映射到标准索引序列
- 显示字符串的集合和子集
- 使用模板化运算符重载 XOR 运算符失败
- 使用XOR查找O(n)-解决方案中的两个字符串是否为变位符
- Cuda:具有位集数组的 XOR 单位集
- 用于子集字符串的 Rcpp 函数
- 如何通过使用 2 位或更多数字的 XOR 运算符来执行此操作C++问题
- 使用 XOR 逻辑查找缺失的数字
- 为什么我的子集和方法不正确?
- 计算总和为 x 的所有整数子集(包括负数)
- 在尝试使用递归查找集合子集的总数时,我遇到了分割错误
- 使用 XOR 操作仅使用 2 个指针反转链表
- 从小于或等于某个 N 的数字列表中最小化或找到 n 个理想的子集和
- 使用 Rcpp 的高效矩阵子集
- 如何在c ++中使用XOR解密文件?
- 返回给定 SEXP 的子集,而无需知道实际的内部数据类型
- 使用递归从子集和中查找最大和
- 给定一个长度为n的数组,找到子集的数量,其中子集的XOR等于给定数量