0

たとえば、この多項式時間に関するすべてが私を混乱させます。セットから合計が 0 になる 4 つの整数のみを選択する多項式時間アルゴリズムでプログラムを作成したいと考えています。たとえば、次の整数のセット {8, 20, 3, -2, 3, 7, 16, -9} があるとします。4 以外のすべての可能な長さをチェックする必要なく、多項式時間のセットから合計が 0 になる 4 つの異なる整数のみを選択するにはどうすればよいですか? プログラムでは、4 以外の可能な長さを検索する必要がないことに注意してください。私の予想される解は {8, 3, -2, -9} = 0 です。セット { 8、20、3、-2、3、7、16、-9}。

編集:元のセットの長さだけを 8 から 100 の整数に増やしたとしても、{8, 3, -2, -9} の多項式時間解が見つかりますか? 0 ですが、100 個の整数のセットから、入力のサイズ (つまり、入力を格納するために使用されるビット数) に関して多項式の高速になりますか?

4

2 に答える 2

0

繰り返しなしですべての 4 回転を試してください。これには(N^4-6N³+11N²-6N)/24、一定時間内に行われる最大試行回数が必要です。

8 + 20 + 3 - 2 = 29
8 + 20 + 3 + 3 = 34
8 + 20 + 3 + 7 = 38
8 + 20 + 3 + 16 = 47
8 + 20 + 3 - 9 = 22
8 + 20 - 2 + 3 = 29
8 + 20 - 2 + 7 = 33
8 + 20 - 2 + 16 = 42
8 + 20 - 2 - 9 = 17
8 + 20 + 3 + 7 = 38
8 + 20 + 3 + 16 = 47
8 + 20 + 3 - 9 = 22
8 + 20 + 7 + 16 = 51
8 + 20 + 7 - 9 = 26
8 + 20 + 16 - 9 = 35
8 + 3 - 2 + 3 = 12
8 + 3 - 2 + 7 = 16
8 + 3 - 2 + 16 = 25
8 + 3 - 2 - 9 = 0    <==
8 + 3 + 3 + 7 = 21
8 + 3 + 3 + 16 = 30
8 + 3 + 3 - 9 = 5
8 + 3 + 7 + 16 = 34
8 + 3 + 7 - 9 = 9
8 + 3 + 16 - 9 = 18
8 - 2 + 3 + 7 = 16
8 - 2 + 3 + 16 = 25
8 - 2 + 3 - 9 = 0    <==
8 - 2 + 7 + 16 = 29
8 - 2 + 7 - 9 = 4
8 - 2 + 16 - 9 = 13
8 + 3 + 7 + 16 = 34
8 + 3 + 7 - 9 = 9
8 + 3 + 16 - 9 = 18
8 + 7 + 16 - 9 = 22
20 + 3 - 2 + 3 = 24
20 + 3 - 2 + 7 = 28
20 + 3 - 2 + 16 = 37
20 + 3 - 2 - 9 = 12
20 + 3 + 3 + 7 = 33
20 + 3 + 3 + 16 = 42
20 + 3 + 3 - 9 = 17
20 + 3 + 7 + 16 = 46
20 + 3 + 7 - 9 = 21
20 + 3 + 16 - 9 = 30
20 - 2 + 3 + 7 = 28
20 - 2 + 3 + 16 = 37
20 - 2 + 3 - 9 = 12
20 - 2 + 7 + 16 = 41
20 - 2 + 7 - 9 = 16
20 - 2 + 16 - 9 = 25
20 + 3 + 7 + 16 = 46
20 + 3 + 7 - 9 = 21
20 + 3 + 16 - 9 = 30
20 + 7 + 16 - 9 = 34
3 - 2 + 3 + 7 = 11
3 - 2 + 3 + 16 = 20
3 - 2 + 3 - 9 = -5
3 - 2 + 7 + 16 = 24
3 - 2 + 7 - 9 = -1
3 - 2 + 16 - 9 = 8
3 + 3 + 7 + 16 = 29
3 + 3 + 7 - 9 = 4
3 + 3 + 16 - 9 = 13
3 + 7 + 16 - 9 = 17
- 2 + 3 + 7 + 16 = 24
- 2 + 3 + 7 - 9 = -1
- 2 + 3 + 16 - 9 = 8
- 2 + 7 + 16 - 9 = 12
3 + 7 + 16 - 9 = 17

更新

OPのリクエストで、解決策が見つかったときに停止しました。

8 + 20 + 3 - 2 = 29
8 + 20 + 3 + 3 = 34
8 + 20 + 3 + 7 = 38
8 + 20 + 3 + 16 = 47
8 + 20 + 3 - 9 = 22
8 + 20 - 2 + 3 = 29
8 + 20 - 2 + 7 = 33
8 + 20 - 2 + 16 = 42
8 + 20 - 2 - 9 = 17
8 + 20 + 3 + 7 = 38
8 + 20 + 3 + 16 = 47
8 + 20 + 3 - 9 = 22
8 + 20 + 7 + 16 = 51
8 + 20 + 7 - 9 = 26
8 + 20 + 16 - 9 = 35
8 + 3 - 2 + 3 = 12
8 + 3 - 2 + 7 = 16
8 + 3 - 2 + 16 = 25
8 + 3 - 2 - 9 = 0    <==
于 2016-02-02T13:16:55.973 に答える
0

次のアルゴリズムは O(N^3 * logN) で実行されます。

#include <algorithm>
#include <iostream>
#include <tuple>
#include <vector>

using quadruple = std::tuple<int, int, int, int>;

std::vector<quadruple> find(std::vector<int> vec) {
  std::sort(vec.begin(), vec.end());
  vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
  std::vector<quadruple> ret;
  for (auto i = 0u; i + 3 < vec.size(); ++i) {
    for (auto j = i + 1; j + 2 < vec.size(); ++j) {
      for (auto k = j + 1; k + 1 < vec.size(); ++k) {
        auto target = 0 - vec[i] - vec[j] - vec[k];
        auto it = std::lower_bound(vec.begin() + k + 1,
            vec.end(),
            target);
        if (it != vec.end() && *it == target) {
          ret.push_back(std::make_tuple(
              vec[i], vec[j], vec[k], target));
        }
      }
    }
  }
  return ret;
}

int main() {
  std::vector<int> input = {8, 20, 3, -2, 3, 7, 16, -9};
  auto output = find(input);
  for (auto& quad : output) {
    std::cout << std::get<0>(quad) << ' '
              << std::get<1>(quad) << ' '
              << std::get<2>(quad) << ' '
              << std::get<3>(quad) << std::endl;
  }
}
于 2016-02-02T13:56:36.430 に答える