我正在尝试解决一个给定整数n
和整数a
的数组的问题-n
可以表示为{{ 1}},这样系数也是正个整数。
我看到了C: check if an integer is linear combination of elements in an array并在C语言中实现了它,但并非在所有情况下都有效。
a
但是,如果int gcd(int a, int b) {
if (a == 0) {
return b;
}
return gcd(b % a, a);
}
bool can_be_changed(const int a[], int len, int val) {
for (int i = 0; i < len - 1; i++) {
for (int j = i + 1; j < len; j++) {
if (val % gcd(a[i], a[j]) == 0) {
return true;
}
}
}
return false;
}
和a = {4,5,6}
的代码将返回true,原因是val=7
,而gcd(4,5) = 1
的结果将为7 % gcd(4,5) == 0
,因此返回true
不应该。
感谢您的帮助,谢谢!
答案 0 :(得分:1)
当您将系数限制为正整数时,此问题是NP完全的(只要len
是输入的一部分并且没有固定)。因此,真正有效的解决方案将不会发生。 (如果您想四处搜寻,则称为无界子集总和问题; a proof of its hardness is here。)
The most efficient algorithm I've found is from this paper:
⊕ t 操作是一个“封顶汇总集”,也在论文中进行了描述:它基本上是这样运行的(用Python绘制):
def capped_sumset(a, b, t): # a, b sets of naturals, t natural
a0 = a | {0}
b0 = b | {0}
return {
x+y
for x in a0
for y in b0
if x+y <= t
}
在C中实现此功能最困难的部分是所有设置的操作。一旦您能够很好地实现整数集,算法本身就不会太糟糕。
当然,如果您不关心效率,则可以使用算法基本情况中提到的“经典动态程序”; you can find a detailed explanation with examples in several programming languages here。但是要为指数运行时间做好准备!