在编程竞赛中,一个问题是:
计算等式的所有解:
x + 4y + 4z = n
。你将会 给定n
,您将确定解决方案的数量。假设x,y和z是正整数。
我考虑过使用三重for循环(暴力),但效率不高,导致TIME LIMIT超出限制。 (因为n可能= 1000,000):
int sol = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n / 4; j++)
{
for (int k = 1; k <= n / 4; k++)
{
if (i + 4 * j + 4 * k == n)
sol++;
}
}
}
我的朋友可以解决问题。当我问他时,他说他根本没有使用蛮力。相反,他将等式转换为“系列”(即汇总)。我让他告诉我怎么,但他拒绝了。)
我可以知道吗?
答案 0 :(得分:4)
这是coin change problem的特殊情况,通常通过动态编程解决。
但在这里我们可以详细说明解决方案。我认为x,y,z> 0
x + 4 *(y + z)= n 令y + z = q = p + 1(q> 1,p> 0)
X + 4 * Q = N
X + 4 * P = N-4
x和p有 M = Floor((n-5)/ 4)变体,因此有M个可能的值 q = 2..M + 1 对于每个q> 1,存在y和z的(q-1)变体:q = 1 +(q-1)= 2 +(q-2)+ .. +(q-1)+1
所以我们 N = 1 + 2 + 3 + ... + M = M *(M + 1)/ 2 解决方案
示例:
n = 15;
M =(15-5)div 4 = 2
N = 3
(3,1,2),(3,2,1),(7,1,1)
答案 1 :(得分:1)
首先请注意,n-x
必须可以被4
整除。首先找到x
可以采用的最小值:
start = 4
while ((n - start) % 4 != 0)
{
start = start + 1
}
从现在开始,您知道x
将从[start, start+4, start+8 ...]
获取值。现在,您可以通过简单的计数循环来计算解决方案的数量:
count = 0
for (x = start; x < n - 4; x = x + 4)
{
y_z_sum = (n - x) / 4
count = count + y_z_sum - 1
}
对于x
的每个选项,我们都可以计算y+z
的值。对于y+z
的每个值,有y+z-1
个可能的选择(因为y
的范围从1到y+z-1
,假设y
和z
是{{1}}两个正整数)。
代替O(n 3 )运行时间的强力解决方案,您可以通过这种方式实现O(n)。
答案 2 :(得分:-1)
这是一个经典的线性代数问题。请参考任何关于如何求解线性方程组的线性代数教科书。一种这样的方法称为Gaussian Elimination。