好的,所以我必须解决这个问题,其中用户提供了7个或k
个数字的列表,我必须说明有多少种方法可以获得21
或{{1使用这些数字的和和减法。 我必须使用所有数字。
例如,用户给出数字:(1 3 4 5 9 1 7)。我可以将所有这些数字放入一个长度为7的数组中,并计算我使用这些数字的总和和/或子数的次数:
n
。
此问题的代码已经完成:
1 +/- 3 +/- 4 +/- 5 +/- 9 +/- 1 +/- 7
正如你所看到的,这使得DFS(深度优先搜索)能够找到有多少种方法可以获得21.现在,实际问题是如何知道有多少种方法可以获得21 使用给定数字的组合,我必须再次使用它们。例如,用户提供数字:
count-twenty-one(int* dig, int n, int pos, int sum, int res) {
if (pos==n) {
if(sum==21)
return res++;
}
count-twenty-one(dig, n, pos+1, sum+dig[pos], res)
count-twenty-one(dig, n, pos+1, sum-dig[pos], res)
}
。我无法使用0 + 0 - 0 + 0 + 2 + 1 + 0来获得21但是如果我将2和1和sum / sub与其他0相加,我可以得到21。
(0 0 0 0 2 1 0)
让我们说用户现在给出(2 3 9 8 5 0 7)。有了这个,我可以使用0 + 0 + 0 - 0 + 21 -0 = 21
这样的数字,并尝试查看有多少种方法可以获得所需的数字。但是我可以再次23 98 5 7
。
所以我猜主要的问题是从(1到k)获得所有可能的数字组合 - K是数字列表的长度 - 然后在所有的数字中使用239 8 507
他们。我该怎么做呢?我正在使用C ++和数组。
修改:
可以通过获取给定数组的所有可能分区来解决此问题,然后通过count-twenty-one
将这些分区放入其中。有什么想法吗?
编辑2 :
这些号码已被排序'这意味着使用count-twenty-one
,我无法形成(2 3 9 8 5 0 7)
答案 0 :(得分:0)
对于蛮力方法,以下内容可能有所帮助:https://ideone.com/jAVRDk
void print(const std::vector<int>& digits,
const std::vector<int>& seps,
const std::vector<std::string>& s) {
std::cout << digits[0];
for (std::size_t i = 0; i != seps.size(); ++i) {
std::cout << s[seps[i]] << digits[i + 1] ;
}
std::cout << std::endl;
}
bool next(std::vector<int>& seps)
{
for (auto it = seps.rbegin(); it != seps.rend(); ++it) {
if (++*it == 3) {
*it = 0;
} else {
return true;
}
}
return false;
}
void foo(std::vector<int> digits)
{
const std::vector<std::string> s = {"", " + ", " - "};
std::sort(digits.begin(), digits.end());
do {
std::vector<int> seps(digits.size() - 1, 0);
do {
print(digits, seps, s);
} while (next(seps));
} while (std::next_permutation(digits.begin(), digits.end()));
}