我有两个数字:6& 10
我想使用这两个数字的组合来尽可能接近另一个数字。
例如,要达到9,我需要1 6,其余3。 其他例子:
6: [6]
10: [10]
12: [6, 6]
18: [6, 6, 6]
20: [10, 10]
24: [6, 6, 6, 6]
26: [10, 10, 6]
28: [10, 6, 6, 6]
30: [10, 10, 10]
32: [10, 10, 6, 6]
我需要一种能够找到任意给定数量的最小组合数的算法,优先选择具有最小余数的组合。即
38: [10, 10, 10, 6] - 2 remaining
38: [10, 10, 6, 6, 6] - no remainder, so preferred result
我希望我已经清楚地解释了这一点,如果我需要澄清,请告诉我。
更新: 澄清一下,这是处理实物的现实问题。数字6&图10对应于包含6或10个量的产品的倍数的包装箱。我们接受任何数量的这些产品的订单,并且想要计算可以组成订单的最小数量的纸箱,然后将剩余部分添加为单独的qtys。
客户可能需要订购39的数量,因此我需要知道最少数量的6/10数量的纸箱来组成订单,剩余的最小数量是优先权。
客户也可以订购1,2,3,4,5,6 .....的qtys,最多约300个。
答案 0 :(得分:0)
考虑到你想要在a和b的因子中对n进行因子分解,那么你只需要将两种可能的方法分解,并检查哪一种方法给你最小的余数。
所以,你可以这样:
def factorize(a, b, n):
return n/a, (n%a)/b, (n%a)%b
def factorize_min(a, b, n):
na1, nb1, r1 = factorize(a, b, n)
nb2, na2, r2 = factorize(b, a, n)
return (na1, nb1) if r1 < r2 else (na2, nb2)
def factorize_min_list(a, b, n):
na, nb = factorize_min(a, b, n)
return [a]*na + [b]*nb
并像这样使用它:
for n in (6,10,12,18,20,24,26,28,30,32):
print factorize_min_list(6, 10, n)
这会给你:
[6]
[10]
[6, 6]
[6, 6, 6]
[10, 10]
[6, 6, 6, 6]
[6, 10, 10]
[6, 10, 10]
[10, 10, 10]
[10, 10, 10]
答案 1 :(得分:0)
这种change-making problem可以通过动态编程有效地解决。请注意,如果需要sum,则无法精确生成(如示例中的9) - 检查DP表的下邻居单元格。
答案 2 :(得分:0)
这或多或少是硬币问题。在Frobenius数字之上,可以构建所有值。这里我们有6个和10个不是互质的。因此,我们可以除以最大公约数(2)得到3和5这是互质的。然后我们得到Frobenius数3 * 5 - 5 - 3 = 7.这意味着所有偶数值&gt; 14可以使用6和10个硬币建造。价值很少,你可以只列出一个清单:
所以算法如下:
32(或33)的例子:
答案 3 :(得分:0)
以下是使用动态编程解决问题的C版本。 编译之后,您可以使用项目总数作为参数运行它 它将输出由标签分隔的包装尺寸10和6 然后是他们的总和。 我从德国维基百科页面上获取了关于背包问题的算法 data url
在开头的评论中引用:
/*
U = { 10, 6 } n = 2
w = { 10, 6 }
v = { 2, 1 }
Eingabe: U, B, w, v wie oben beschrieben
R := [1…(n+1), 0…B]-Matrix, mit Einträgen 0
FOR i = n … 1
FOR j = 1 … B
IF w(i) <= j
R[i,j] := max( v(i) + R[i+1, j-w(i)], R[i+1,j]\
)
ELSE
R[i,j] := R[i+1,j]
Ausgabe: R[1,B]
*/
#include <stdlib.h>
#include <stdio.h>
int n = 2;
int main(int argc, char** argv) {
int w[3] = { -1, 10, 6 };
int v[3] = { -1, 10, 6 };
int B = atoi(argv[1]);
size_t sz = ((B+1)*3*sizeof(int));
int* R = malloc(sz);
memset(R, 0, sz);
for(int i = n; i > 0; i--) {
for(int j = 1; j <= B; j++) {
int b = R[i+1,j];
if(w[i] <= j) {
// max( v(i) + R[i+1, j-w(i)], R[i+1,j] )
int a = v[i] + R[i+1, j-w[i]];
R[i,j] = a>b?a:b;
} else {
R[i,j] = b;
}
}
}
int k = R[1,B];
while(R[1,k]>0){
int j = R[1,k];;
for(int i = n; i > 0; i--) {
int t = R[1,k-w[i]];
if(t == k - w[i]) {
j = w[i];
}
}
printf("%i\t",j);
k = k-j;
}
printf("\n%i\n", R[1,B]);
return 0;
}