避免蛮力:计算解决方案

时间:2011-11-23 08:08:12

标签: algorithm brute-force series

在编程竞赛中,一个问题是:

  

计算等式的所有解: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++;
   }
 }
}

我的朋友可以解决问题。当我问他时,他说他根本没有使用蛮力。相反,他将等式转换为“系列”(即汇总)。我让他告诉我怎么,但他拒绝了。)

我可以知道吗?

3 个答案:

答案 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,假设yz是{{1}}两个正整数)。

代替O(n 3 )运行时间的强力解决方案,您可以通过这种方式实现O(n)。

答案 2 :(得分:-1)

这是一个经典的线性代数问题。请参考任何关于如何求解线性方程组的线性代数教科书。一种这样的方法称为Gaussian Elimination

相关问题