有一面大小为4xN
的墙。我们有无数个大小为4x1
和1x4
的砖块。砖在墙上的排列方式总数是多少,每次都会出现新的配置?
对于N = 1
,砖块只能以1
格式铺设。对于N = 7
,我们可以铺设砖块的方法之一是
为N = 7
我使用动态编程解决了这个问题:
static int computeBricks(int n)
{
if(n <= 3) { return 1; }
int[] table = new int[n+1];
table[0] = 1;
table[1] = 1;
table[2] = 1;
table[3] = 1;
for(int i = 4; i <= n; ++i)
{
table[i] = table[i-1] + table[i-4];
}
return table[n];
}
但它只是一个组合:猜测+直觉。我完全不明白这个解决方案。为什么table[i] = table[i-1] + table[i-4]
?
它看起来不像硬币更换问题吗?
使用a
种硬币更改金额n
的方法数量等于:
使用除第一种硬币之外的所有硬币更改金额a
的方法数量,以及使用所有a - d
种硬币更改金额n
的方法数量,其中{{1}是第一种硬币的面额。
但我也不明白我们如何使用这个想法解决原始问题
答案 0 :(得分:5)
为了完成,您可以使用简单的计数技术,无需算法。
你有N个点。你有两种方法可以填充斑点:一次一个(垂直砖块),或一次填充4个连续点(水平砖块)。您可以重新表述:这是K
个K
垂直砖中N/4
堆4个水平砖(N-(3*K)
介于0和choose(n, k)
之间)的数量(对于每堆4个水平砖,与1个垂直砖相比,你会失去3个点 - 这就是你的[n-4]在原始算法中的来源。)
让我们用一个例子来说明。首先,我在下面使用的符号N = 15
是数学combination“n选择k”,即
现在让我们来看看这个例子吧。你可以用K = 0
点做什么?
您有VVVVVVVVVVVVVVV
堆水平砖(H)和15个垂直砖(V):choose(15, 0) = 1
。这样做的方法有K = 1
或者您可以将VVVVHVVVVVVV
H放置在某处(通过将4 V替换为1 H而丢失三个点):choose(15-3, 1) = choose(12, 1) = 12
。这样做的方法有K = 2
或者您可以放置VVHVVVVVH
H(通过将8 V替换为2 H而丢失6个点):choose(15-6, 2) = choose(9, 2) = 36
。这样做的方法有K = 3
或者您可以放置HVVHHV
H(通过将3 V替换为3 H而丢失9个点):choose(15-9, 3) = choose(6, 3) = 20
。这样做的方法有max K = 15/4 = 3
就是这样,你已达到最大水平桩数(1+ 12 + 36 + 20 = 69
)。然后,您只需总结所有这些,以获得填补这些位置的总方式: Context initCtx = new InitialContext();
javax.persistence.EntityManager entityManager =
(javax.persistence.EntityManager)initCtx.lookup(
"java:comp/env/avaliacaoneomind"
);
。
以下是直接从这个解释中得出的通用公式:
最终导致:
答案 1 :(得分:2)
如果列数少于4列,显然只有一种方法可以排列砖块:
1, 12, 123
1, 12, 123
1, 12, 123
1, 12, 123
但是,有两种方法可以为第4列排列砖块 方法1 - 只需将列添加到3列的正确解决方案中:
1234
1234
1234
1234
方式2 - 删除现有的三列并放置四个水平砖:
1111
2222
3333
4444
相同的逻辑适用于所有后续列 - 您可以对N-1进行所有正确的排列并为每个列添加一列或对N-4进行所有正确的排列并水平放置四个砖。
解决方案很简单,因为问题的一个推导 - 你可以放置4个水平砖或4个垂直砖,因为放置1个水平砖将使垂直不可能,反之亦然。
如果墙壁仍为4xN,则此任务将更加困难,但砖块为2x1和1x2。
答案 2 :(得分:0)
f(n) = f(n-1) + f(n-4) if n >= 4 <p>
f(n) = 1 if 0 <= n < 4