Algorithm 网格着色的多种方法
有nx1的网格。你必须用至少r红细胞,至少g绿细胞,至少b蓝细胞给它着色。(n+r+g0) ma++; 如果(g>0) ma++; 如果(b>0) ma++; 返回ma; } 如果(r>0) ma+=func(r-1,g,b,id+1); 如果(g>0) ma+=func(r,g-1,b,id+1); 如果(b>0) ma+=func(r,g,b-1,id+1); 如果(r+g+bAlgorithm 网格着色的多种方法,algorithm,permutation,Algorithm,Permutation,有nx1的网格。你必须用至少r红细胞,至少g绿细胞,至少b蓝细胞给它着色。(n+r+g0) ma++; 如果(g>0) ma++; 如果(b>0) ma++; 返回ma; } 如果(r>0) ma+=func(r-1,g,b,id+1); 如果(g>0) ma+=func(r,g-1,b,id+1); 如果(b>0) ma+=func(r,g,b-1,id+1); 如果(r+g+bn时。如果你“从底部开始”,你可能不会进入这个场景,但这似乎更复杂。@Dukeling,是的,你是对的,我没有提到它
}假设它们的数量是
f(n,r,g,b)
,那么我们有以下递归:
f(n,r,g,b)=f(n-1,r,g,b)*3+f(n-1,r-1,g,b)+f(n-1,r,g-1,b)+f(n-1,r,g,b-1)
我们也知道基本情况:f(1,1,0,0)=f(1,0,1,0)=f(1,0,0,1)=1
。从底部开始,在上面递归建立f(n,r,g,b)。(如果使用memonization而不是for循环,则这很简单)。运行时间为O(n*r*g*b)
更新:您的代码与我的答案很接近,但首先我应该说这是错误的,其次,您使用了朴素的递归,这会导致指数级的运行时间,分配一个大小为nrg*b的数组,以防止重新计算已经计算过的答案。参见记忆的实例。此外,该算法可接受的时间和空间复杂度是多少?另外,
f(n,r,g,b)=0
当r+g+b>n
时。如果你“从底部开始”,你可能不会进入这个场景,但这似乎更复杂。@Dukeling,是的,你是对的,我没有提到它,因为我认为这是显而易见的,而且是关于实现的细节。你的递归关系看起来是错误的。加在一起的情况应该是相互排斥的,即任何给定的配置都应该只计入总和的一个项中。考虑,例如,R=G=B=1,n=10。包含3个r、g、b的9-配置产生3个新的10个配置,但您的表达式将其计算为至少产生6个。@jwpat7,可能您是对的,我稍后会考虑,如果是错误的,我会修复它(我也不确定是否正确,但为了使它正确,似乎很容易添加另一个维度来跟踪最后一个项目的颜色,这不会改变运行时间)。
enter code here
int func(int id, int r, int g, int b)
{
int ma = 0;
if (id == n) {
if (r > 0)
ma++;
if (g > 0)
ma++;
if (b > 0)
ma++;
return ma;
}
if (r > 0)
ma += func(r-1, g, b, id + 1);
if (g > 0)
ma += func(r, g-1, b, id + 1);
if (b > 0)
ma += func(r, g, b-1, id + 1);
if (r + g + b < n - id) {
ma += func(r, g, b, id + 1);
}
return ma;