我认为应该使用动态编程来解决这个问题。
这是一个伪代码解决方案(我还没有测试过,但我认为它应该可以工作):
parts = the number of shapes we want to fit as a vector
plates = the of plates we can use as a matrix (vector of vector)
function findSolution(parts, usedPlates):
if parts < 0: //all elements < 0
return usedPlates;
else:
bestSolution = null //or anything that shows that there is no solution yet
for X in plates:
if (parts > 0 on any index where X is > 0): //prevents an infinite loop (or stack overflow because of the recursion) that would occur using only e.g. the plate B from your question
used = findParts(parts - X, used.add(X)); //elementwise subtraction; recursion
if (used.length < best.length):
//the solution is better than the current best one
best = used;
//return the best solution that was found
return best
使用您问题中的值,初始变量将是:
parts = [10, 8, 9]
plates = [[2, 3, 1], [1, 0, 3], [2, 2, 2]]
你会像这样启动函数:
solution = findSolution(parts /*= [10, 8, 9]*/, new empty list);
//solution would probably be [A, A, C, C, C], but also [C, C, C, C, C] would be possible (but in every case the solution has the optimal length of 5)
使用此算法,您可以使用递归(这是大多数动态规划算法所做的)将问题划分为更小的问题。
这种方法的时间复杂度并不高,因为您必须搜索所有可能的解决方案。
根据master theorem,时间复杂度应该类似于: O(n^(log_b(a))) 其中 n = a = 使用的板数(在您的示例 3 中)。 b(对数的底)不能在这里计算(或者至少我不知道如何计算),但我认为它会接近 1,这使得它成为一个很大的指数。但这也取决于部件向量中条目的大小和车牌向量中的项目(需要更少的车牌 -> 更好的时间复杂度,需要更多的车牌 -> 糟糕的时间复杂度)。
所以时间复杂度不是很好。对于较大的问题,这将需要很长时间,但对于像您的问题这样的小问题,它应该可以工作。