Don't know if I phrased it good, but I'll try to explain it further here:
So, I have an array of numbers, let's say 1 2 3 4 5 6 7 8 9 10 11 14
and I need to write an algorithm to split up the array into 3 number sized array with equal sums, which in this case would be:
{14,2,4} {11,6,3} {10,1,9} {5,7,8}
- i think i got it.
So, what I have now in my head is:
Checking every possible sum of the integers, and putting three indexes used and the sum into a structure.
Then, with an array of structures, I would sort them by sum and would search for N/3
number of sums, and if found, I print out the numbers according to their indexes.
The algorithm includes running through all numbers a lot of times, so it would be very slow. Can anyone suggest a better algorithm? If someone would like to give pieces of code, I can program in C
and i have started learning Java
.
Thank you!
答案 0 :(得分:1)
You don't say if you're always going to start with 12 numbers.
You have the following array of numbers: 1 2 3 4 5 6 7 8 9 10 11 14
The count of the array of numbers must be divisible by 3. If not, there is no solution.
Sum the array of numbers. In this case, the sum is 80.
We have 12 numbers, so we have 4 groups of 3. Divide the sum by the number of groups, which is 80 / 4, or 20. If this division doesn't yield an integer, there is no solution.
Go through the array of numbers, three numbers at a time, once, and keep the triplets that sum to 20. You can use a 12 bit binary integer, starting at zero and incrementing by 1, to select the triplets. When the binary integer has 3 one bits, use the location of those bits as an index to your array of numbers.
Check to see if the group number of triplets exists and uses all of the numbers in the array. If so, you have your solution. If not, there is no solution.
Edited to add: It turns out that there are 4 solutions for the array of numbers given in the question:
(2,4,14); (3,6,11); (1,9,10); (5,7,8)
(2,4,14); (1,8,11); (3,7,10); (5,6,9)
(1,5,14); (3,6,11); (2,8,10); (4,7,9)
(1,5,14); (2,7,11); (4,6,10); (3,8,9)
I wrote the code just to see how long it would take to produce a solution. It ran in less than a second.
答案 1 :(得分:0)
Well, it's a hard problem. A bit difficult to write code for it, and it might take a long time to solve if you have lots of numbers.
First you check whether a solution can be possible. You have 12 numbers (if it was 11 or 13 you couldn't put them in groups of 3), so you want four groups of 3. The sum is 80, that's also good because you now need four groups of three numbers adding up to 20 each; if the sum was 79 or 78 that wouldn't work.
Sort the numbers in descending order. The biggest number must be in some group, so start with that: 14. 14 can be combined with 5,1 or 4,2. You check both possibilities.
The next biggest number must be in some group, so we take 11. Which could be combined with 8,1 or 7,2 or 6,3 or 5,4. If the first group was (14,5,1) then the second can be (11,7,2) or (11,6,3). If the first group was (14,4,2) then the second can be (11,8,1) or (11,6,3). So your choices don't grow too much.
So you can write a recursive function where you add one more group each time; each group that you add contains the largest remaining number, plus two numbers so the sum adds up to 20; you have to remove the numbers that you already picked. That's the rough idea.
答案 2 :(得分:0)
(草图)动态编程方法:
拥有3个整数的数组。有一种方法可以将整数标记为已使用。将第一个未标记的数字添加到阵列并将其标记为已使用。添加下一个未标记的数字,看看总和是否仍低于目标总和(您知道如何获得它)。另外尝试另一个号码。找出缺少的数字并查找它(确保其未标记)。让我们说你找到了它。你将拥有你的三元组(你将它存储在某个地方,这是我将不会介绍的记忆部分,以简化它)。寻找另一个三胞胎。
将每个数字添加到三元组后,以递归方式查找下一个数字,这样您就可以返回并尝试另一个组合,如果这个没有用。它是如何工作的,在某些时候你可能会在没有构建三元组的情况下到达数组的末尾。然后,您必须返回递归调用以尝试其他数字。
只有在能够标记所有数字时才能完成。
这里肯定有改进的余地,但是如果你理解了什么是动态编程,你应该得到它。