给定N个列表,其数字可以在1到100之间。
我想要多种方法来选择数字,每个不同的列表中的一个不允许重复。
注意:如果选择的任何数字不同,则两种方式不同。
示例:
List 1 : 5, 100, 1
List 2 : 2
List 3 : 5, 100
List 4 : 2, 5, 100
因为我想从每个中选择一个数字而不重复。
在这种情况下的答案是:2(1,2,5,100和1,2,100,5)。
我的方法:我尝试使用包含和排除原则解决它。但是如何找到所有交叉点?
我在想,可以通过匹配同时获取1组中的列表和相应的映射数字来解决它吗?
N最多可以为10,每个列表的数字可以在1-100之间。
此外,每个列表中只有一个数字。
答案 0 :(得分:0)
这是所提出的@robertking算法的实现
注意:
std::vector<bool>
存储已使用的数字(针对STL的大多数实现中的bool作为位进行了优化)。cache
变量(动态编程)加速以前获得的结果进行大搜索。TRACE
define打印解决方案。代码(在Windows中使用C ++ 11在GCC 4.9.0中测试):
#include <iostream>
#include <bitset>
#include <vector>
#include <map>
#define TRACE
typedef std::vector<bool> used_numbers_t;
typedef std::vector<int> list_t;
typedef std::vector<list_t> lists_t;
typedef std::map<std::pair<used_numbers_t, unsigned int>, int> cache_t;
cache_t cache;
long solve(used_numbers_t& used_numbers, const lists_t& lists, list_t& generated_solution, unsigned int list_idx = 0, int solutions = 0) {
if (list_idx == lists.size()) {
#ifdef TRACE
for (auto gs : generated_solution) {
std::cout << gs << ",";
}
std::cout << std::endl;
#endif
return solutions + 1;
}
auto key = std::make_pair(used_numbers, list_idx);
auto it = cache.find(key);
if (it != cache.cend()) {
return it->second;
}
long actual_solutions = 0;
auto& processing_list = lists[list_idx];
for (unsigned int idx = 0; idx < processing_list.size(); idx++) {
if (!used_numbers[processing_list[idx] - 1]) {
used_numbers[processing_list[idx] - 1] = true;
#ifdef TRACE
generated_solution.push_back(processing_list[idx]);
#endif
actual_solutions += solve(used_numbers, lists, generated_solution, list_idx + 1, solutions);
#ifdef TRACE
generated_solution.pop_back();
#endif
used_numbers[processing_list[idx] - 1] = false;
}
}
cache.insert(std::make_pair(key, actual_solutions));
return solutions + actual_solutions;
}
int main(int argc, char* argv[]) {
lists_t lists{{5, 100, 1}, {2}, {5, 100}, {2, 5, 100}};
used_numbers_t used_numbers(100);
list_t generated_solution;
long solutions = solve(used_numbers, lists, generated_solution);
std::cout << "The total number of solutions is: " << solutions << std::endl;
return 0;
}
获得输出:
1,2,5,100,
1,2,100,5,
The total number of solutions is: 2