我是CS第二年的学生。在我的算法和数据结构课程中,我承担了以下问题:
Input:
2<=r<=20
2<=o<=10
0<=di<=100
Output:
number of combinations
or "NO" if there are none
我必须找到正确组合的数量。正确的组合是每个整数都分配给某个组的组合,没有一个组是空的,每个组中的整数之和是相同的:
对于一个例子:
r = 4;
di = {5, 4, 5, 6}
o = 2;
因此每组中的整数总和应该加起来为10:
5 + 4 + 5 + 6 = 20
20 / o = 20 / 2 = 10
所以我们可以制作以下小组:
{5, 5}, {4, 6}
{5, 5}, {6, 4}
{5, 5}, {4, 6}
{5, 5}, {6, 5}
正如我们所看到的,每个组合都与第一个组合基本相同。(组中元素的顺序无关紧要。)
所以实际上我们只有一个正确的组合:{5,5},{4,6}。这意味着输出等于一。
其他例子:
r = 4;
di = {10, 2, 8, 6}
o = 2;
10 + 2 + 8 + 6 = 26;
26 / o = 26 / 2 = 13
无法对这些整数求和,因此输出为&#34; NO&#34;。
我有一个关于完成这件事的想法:
struct Input { // holds data
int num; // number of integers
int groups; // number of groups
int sumPerGroup; // sum of integers per group
int *integers; // said integers
};
bool f(bool *t, int s) { // generates binary numbers (right to left"
int i = 0;
while (t[i]) i++;
t[i] = 1;
if (i >= s) return true;
if (!t[i + 1])
for (int j = i - 1; j >= 0; j--)
t[j] = 0;
return false;
}
void solve(Input *input, int &result) {
bool bin[input->num]; // holds generated binary numbers
bool used[input->num]; // integers already used
for (int i = 0; i < input->num; i++) {
bin[i] = 0;
used[i] = 0;
}
int solved = 0;
do {
int sum = 0;
for (int i = 0; i < input->num; i++) { // checking if generated combination gets me nice sum
if (sum > input->sumPerGroup) break;
if (bin[i] && !used[i]) sum += input->integers[i]; // if generated combination wasnt used before, start adding up
if (sum == input->sumPerGroup) { // if its add up as it shoul
for (int j = 0; j < input->num; j++) used[j] = bin[j]; // mark integers as used
solved ++; // and mark group as solved
sum = 0;
}
if (udane == input->groups) { // if the number of solved groups is equal to number of groups
result ++; // it means we found another correct combination
solved = 0;
}
}
} while (!f(bin, input->num)); // as long as I can get more combinations
}
所以,主要的想法是: 我生成一些数字组合作为二进制数 我检查一下这个组合是否能给我带来不错的收益 如果是的话,我会注意到它 4.冲洗并重复。
因此,对于来自第一个示例{5,4,5,6}的输入,分为两组:
5 4 5 6
-------
0 0 0 0
1 0 0 0
...
1 0 1 0 -> this one is fine, becouse 5 + 5 = 10; I mark it as used
1 1 1 0
...
0 1 0 1 -> another one works (4 + 6 = 10); Marked as used
So far i got myself 2 working groups which is equal to 2 groups - job done, it's a correct combination.
我的想法背后的真正问题是,一旦我将其标记为&#34;使用&#34;我就无法使用某个整数。这种方式在更复杂的例子中我会错过很多正确的组。我的问题是,这种问题的正确方法是什么?我已经尝试过递归方法,但它没有做得更好(出于同样的原因)
我的另一个想法是每次在标记某些组时使用输入来排列(例如std:next_permutate(...))整数,但即使在看起来很傻的纸上也是如此。
我不是要求你为我解决这个问题,但是如果你能指出我的推理中存在的任何瑕疵都会很糟糕。
此外,不是母语人士。如果我屠杀任何一句话(我知道我做过),我想提前道歉。