algorithm - 集合的每个子集的最小和最大元素的或之和

标签 algorithm set subset logical-operators

给定一个集合 S,对于它的每个非空子集,找到最小和最大的元素并对其进行逻辑或。在所有此类子集中查找这些 OR 的总和。

例如:S = {1, 2, 3},然后是子集

{1} 最小=1 最大=1 或=1

{2} 最小=2 最大=2 或=2

{3} 最小=3 最大=3 或=3

{1, 2} 最小=1 最大=2 或=3

{2, 3} 最小=2 最大=3 OR=3

{1, 3} 最小=1 最大=3 OR=3

{1, 2, 3} 最小=1 最大=3 OR=3

答案是 18。

我已阅读 How to find Sum of differences of maximum and minimum of all possible subset of an array但不能在这里使用该逻辑。

最佳答案

算法

  • 对输入数据进行排序
  • i = 0 到 n 循环,其中 n 是输入的长度,j = i 到 n,因为输入是排序的 input[ i] 将是最小的,input[j] 将是 [i,j]
  • 范围内的最大者
  • 现在我们知道 input[i] 是最小的而 input[j] 是最大的我们也知道有 j - i - 1 数组的中间元素,其组合将产生相同的最低值和最大值,因此我们将低值和高值的 OR 乘以这些中间数字可能的排列总数。
  • 例如。对于 input = [1, 2, 3, 4]i = 0j = 3 即)lowest = 1largest = 4 我们知道元素 [2, 3] 可以出现在子集中而不改变最小值和最大值。 [1, 2, 4], [1, 3, 4], [1, 2, 3, 4] 都是有效的。中间元素可能的组合数是 2 ^ (count of middle elements)
  • 对所有最小和最大的对重复此操作。

这是 C++ 中的代码。

#include <iostream>

int main() {
    vector<int> input {3, 2, 1};
    sort(input.begin(), input.end());
    int answer = 0;
    for(int i=0; i < input.size(); ++i)
    {
        for(int j=i; j < input.size(); ++j)
        {
            int elements = (j - i) - 1;
            int multiple = elements > 0 ? pow(2, elements) : 1;
            answer += ((input[i] | input[j]) * multiple);
            cout << input[i] << ' ' << input[j] << ' ' << answer << endl;
        }
        cout << endl;
    }
    cout <<  answer <<endl;
}

关于algorithm - 集合的每个子集的最小和最大元素的或之和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50323145/

相关文章:

c - ARM V7M 64位划分

python - 在 python 中,如果两个列表都包含公共(public)元素,则从两个元组列表中选取元组

c# - 在 C# 中定义集合访问器时如何避免堆栈溢出错误

algorithm - 分区问题蛮力算法

c - Peterson 的 C 线程并发算法(段错误)

python - 弄清楚如何使用集合和列表

module - 可以在 Raku 中导出子集吗?

c++ - 使用递归从子集总和中找到最大总和

python - 编码德语算法

python - 使用 Python 中的其他值更新 numpy 数组中的值