收藏 分享(赏)

算法201307-回溯法1.ppt

上传人:scg750829 文档编号:8271682 上传时间:2019-06-17 格式:PPT 页数:59 大小:1.13MB
下载 相关 举报
算法201307-回溯法1.ppt_第1页
第1页 / 共59页
算法201307-回溯法1.ppt_第2页
第2页 / 共59页
算法201307-回溯法1.ppt_第3页
第3页 / 共59页
算法201307-回溯法1.ppt_第4页
第4页 / 共59页
算法201307-回溯法1.ppt_第5页
第5页 / 共59页
点击查看更多>>
资源描述

1、第六章 回溯法,6.1 一般方法 6.2 8-王后问题 6.3 子集和数问题 6.4 图的着色问题 6.6 0/1背包问题,什么是回溯,回溯,回溯,入口,出口,回溯,迷宫游戏,什么是回溯法,回溯法是一个既带有系统性又带有跳跃性的的搜索算法,回溯法是以深度优先的方式系统地搜索问题的解, 它适用于解一些组合数较大的问题。,回溯,为什么回溯?,回溯(Trackback)是什么?,怎样回溯?,What,Why,How,应用回溯法解问题时,首先应该明确问题的解空间 一个复杂问题的解决方案可以看作是由若干个小的决策组成的,这些决策构成一个决策序列。 解决一个问题的所有可能的决策序列就构成了该问题的解空间。

2、 解空间中满足约束条件的决策序列称为可行解。 在约束条件下使目标达到最优的可行解称为该问题的最优解。 通常将解空间画成树的形状,称为解空间树,回溯法的基本概念,回溯算法求解问题的类型同贪心算法和动态规划算法求解的问题类型相似,问题的解可以表示成一个n维向量,一般地,每个分量有两个或有限多个取值,而且的取值要满足某个事先给定的约束条件。所有可能的取值的组合构成问题的解向量空间,简称解空间。 由于一个解向量往往对应问题的某个状态,所以解空间又称为问题的状态空间。,一般情况下,问题的解仅是问题解空间的一个子集,要求此子集对应的解必须满足问题的约束条件,满足约束条件的一组取值称为问题的一个可行解,使目

3、标函数取最大或最小值的可行解称为最优解。,回溯法在求问题的所有解时, 要回溯到根结点, 且根结点的所有子树都已被搜索过才结束。 回溯法在求问题的任一解时, 只要搜索到问题的一个解就可以结束。 回溯法在包含问题所有解的解空间树中, 按深度优先的策略, 从根结点出发搜索解空间树。 回溯法搜索至解空间树的任一结点时, 先判断该结点是否肯定不包含问题的解。如果肯定不包含, 则跳过以该结点为根的子树, 逐层向其祖先结点回溯。否则就进入该子树, 继续按深度优先的策略进行搜索。,回溯法的基本概念,问题的解可以用一个n元组(x1, , xn)来表示,其中的xi取自于某个有穷集Si , 并且这些解必须使得某一限

4、界函数P(x1, , xn)取极值。 不断地用修改过的限界函数Pi(x1,xn)去测试正在构造的n元组的部分向量, 看是否可能导致最优解, 如果不能, 就将可能要测试的mi+1 mn个向量略去。 回溯法的解需要满足一组综合的约束条件, 通常分为: 显式约束和隐式约束 显式约束条件: 限定每个x只从一个给定的集合上取值, 满足显式约束的所有元组确定一个可能的解空间例: xi=0 , si=所有非负实数 隐式约束条件: 描述了xi必须彼此相关的情况,回溯法的基本概念,回溯法的基本思想,通过部分解向量逐步增加可行分量来求出解向量。对于一个解向量,假设已经构造得到问题的部分解向量(x1,x2,xk),

5、在部分解向量的基础上,考虑第k+1个分量xk+1的一个取值,可能遇到下面的两种情况:,(1) 部分解向量加入xk+1仍满足约束条件,那么以 为基础继续添加新的分量;,(2) 否则,那么就要考察xk+1的另外一个取值,如果对xk+1的所有取值,都不满足约束条件,那么就回溯到 xk ,即选取xk 的另一个取值 ,同上考察部分解向量。,从k=1开始,逐步扩展部分解(x1,x2,xk) ,就是回溯求解的过程 。,如何表示解空间?,树结构已有成熟的搜索算法,因此可以利用树结构表示问题的解空间。,例: 4-王后问题,在一个4*4棋盘上放4个王后, 使每两个王后之间都不能互相“攻击”, 即使得每两个王后都不

6、能在同一行、同一列及同一条斜线上。 4王后问题可以表示为4-元组(x1, ,x4) ,其中xi是放置王后i所在的列号。 显式约束条件: si=1, 2, 3, 4, 1i4 隐式约束条件: 没有两个xi可以相同, 且没有两个王后可以在同一条斜线上,1,4-王后问题的解空间树,x1=1,x2=2,问题描述: 已知n+1个正数: wi (1in)和M, 要求找出wi的和数是M的所有子集。例: n=4 , (w1, w2, w3, w4 )=(11,13,24,7) , M=31 满足要求的子集是(11, 13, 7)和(24, 7) 用wi的下标来表示解向量更为方便, 因此这两个解向量可以表示为:

7、 (1, 2, 4)和(3, 4) 显式约束条件: xi j | j是wi的下标值, 1jn 隐式约束条件: 要求没有两个xi是相同的, 且相应的wi的和数等于M 为避免产生同一个子集的重复情况(如(1,2,4)和(1,4,2), 附加一个隐式约束条件: xixi+1, 1jn,例:子集和数问题,子集和数问题的解空间树1,解空间树中的路径对应一个向量根结点到自身的 空路径对应一个 空向量( ),树中红色的路径分别对应向量: (4) (1, 2, 4) (2, 3, 4),子集和问题可变长度解空间树,一个问题的解可以有多种表示形式,而这些表示形式都使得所有的解是满足某些约束条件的多元组 子集和数

8、问题的另一种列式表示: 每一个解的子集由一个大小固定的n-元组(x1, , xn)所表示, 它使得xi0,1,1in ; 如果选择wi , 则xi=1 ; 否则xi=0 解向量(1, 2, 4)和(3, 4)可表示为(1,1,0,1)和(0,0,1,1),例:子集和数问题,子集和数问题的解空间树2,注: 结点按D-检索方式编号,从根结点到叶结点的一条路径确定解空间中的一个元组,树中红色路径表示元组(1,1,0,1),子集和问题固定长度 解空间树,解空间树(状态空间树)的术语,问题状态(problem state): 树中的每一个结点确定所求解问题的一个问题状态 状态空间(state space

9、): 由根结点到其他结点的所有路径确定了这个问题的状态空间 解状态(solution states): 是这样一些问题状态S, 对于这些问题状态, 由根到S的那条路径确定了这个解空间中的一个元组 答案状态(answer states): 是这样的一些解状态S, 对于这些解状态而言, 由根到S的这条路径确定了这问题的一个解,静态树(static trees): 树结构与所要解决问题的实例无关 动态树(dynamic trees): 树结构是与实例相关的, 且树结构是动态确定的 活结点: 自己已经生成而其所有的儿子结点还没有全部生成的结点 E-结点(正在扩展的结点): 当前正在生成其儿子结点的活结

10、点 死结点: 不再进一步扩展或者其儿子结点已全部生成的生成结点,解空间树(状态空间树)的术语,在搜索过程中, 如果搜索到一个活结点,则将该活结点转化为扩展结点,并继续搜索该结点的子结点; 如果搜索到一个死结点,且还没有得到问题的解,则向上回溯到它的父结点,如果其父结点当前还是扩展结点,继续搜索其父结点的其它子结点;如果其父结点随着其子结点搜索完毕而变成死结点,则此时需要进一步向上回溯到其祖父结点。 以上过程继续进行,直到得到问题的解,或者最后解空间树的根结点也成为死结点,此时回溯搜索结束。,问题状态的生成,第一种状态生成方法: 当前的E-结点 R 一旦生成一个新的儿子结点C, 这个C结点就变成

11、一个新的E-结点, 当检测完了子树C后, R结点就再次成为E-结点, 生成下一个儿子结点。(该方法也称为深度优先结点生成法) 第二种状态生成方法: 一个E-结点一直保持到变成死结点为止。它又分为两种方法: 宽度优先生成方法(队列方法)和D-检索方法(栈方法) 第一种状态生成方法对应回溯法第二种状态生成方法对应分支-限界法(Ch7),结点2变成E-结点, 它再生成结点3, 路径变为(1, 2), 即王后1在第1列上,王后2在第2列上, 所以结点3被杀死, 此时应回溯,1,开始把根结点作为唯一的活结点, 根结点就成为E-结点而且路径为( ); 接着生成儿子结点, 假定按自然数递增的次序来生成儿子,

12、 那么结点2被生成, 这条路径为(1), 即把王后1放在第1列上,kill,例: 4-王后问题,回溯到结点2生成结点8, 路径变为(1, 3), 则结点8成为E-结点, 它生成结点9和结点11都会被杀死(即它的儿子表示不可能导致答案的棋盘格局), 所以结点8也被杀死, 应回溯,kill,kill,例: 4-王后问题,回溯到结点2生成结点13, 路径变为(1, 4), 结点13成为E-结点, 由于它的儿子表示的是一些不可能导致答案结点的棋盘格局, 因此结点13也被杀死, 应回溯,kill,kill,例: 4-王后问题,结点2的所有儿子表示的都是不可能导致答案的棋盘格局, 因此结点2也被杀死; 再

13、回溯到结点1生成结点18, 路径变为(2),kill,kill,结点18的儿子结点19、结点24被杀死, 应回溯,例: 4-王后问题,结点18生成结点29, 结点29成为E-结点, 路径变为(2,4);,结点29生成结点30, 路径变为(2,4,1),结点30生成结点31, 路径变为(2,4,1,3), 找到一个4-王后问题的可行解,可行解,搜索树,1、针对所给问题定义问题的解空间, 解空间应至少包含问题的一个最优解 2、确定易于搜索的解空间结构 3、以深度优先方式搜索解空间, 并在搜索过程中使用限界函数避免无效搜索,回溯算法的三个步骤,回溯算法的基础问题,1 既然是搜索,应该先有解空间树才可

14、以搜索。,2 既然动态构造解空间树,回溯算法要构造完整的解空间树。,错,实际是按照定义动态构造解空间树,将问题的解得到融入解空间树的生成过程 。,错,结合实际问题的求解,生成的仅是解空间树的 部分结构,称为搜索树。,从根结点出发, 以深度优先方式搜索整个解空间。 首先根结点成为一个活结点, 同时也成为当前的扩展结点。在当前扩展结点处, 搜索向纵深方向移至一个新结点, 该新结点成为一个新的活结点, 并成为当前扩展结点。 如果在当前扩展结点处不能再向纵深方向移动, 则当前扩展结点就成为死结点。此时应回溯至最近的一个活结点处, 并使该活结点成为当前的扩展结点。 回溯法以这种方式递归地在解空间中搜索,

15、 直至找到所要求的解或解空间中已没有活结点时为止。,回溯法搜索过程,回溯算法的形式化描述,假设回溯法要找出所有的答案结点 设(x1,x2,xi-1)是状态空间树中由根到一个结点的路径,而T(x1,xi-1)是下述所有结点xi的集合,它使得对于每一个xi,(x1,x2,xi)是一条由根到结点xi的路径; 假定存在一些限界函数Bi,如果路径(x1,x2,xi)不可能延伸到一个答案结点,则Bi(x1,x2,xi)取假值,否则取真值。 解向量X(1:n)中的第i个分量,就是那些选自集合 T (x1,x2,xi-1)且使Bi为真的xi,如果要求问题的最优解,除了约束条件外,我们还要考虑目标函数的界的满足

16、问题。若问题最优解是使目标函数取最小值的可行解,当前目标函数的最小值为bound,扩展部分解(x1,x2,xi)时,需要考虑(x1,x2,xi)对应目标函数的取值是否已经大于bound,如果已经大于,则停止在部分解(x1,x2,xi)上的扩展,否则可以在部分解(x1,x2,xi)的基础上继续扩展。,回溯算法的形式化描述,procedure BACKTRACK(n) int k, n; local X(1: n); k=1; while (k0) do if ( 还剩有没检验的X(k)使得X(k)T(X(1)X(k-1) and B(X(1)X(k)=TRUE ) then if (X(1) X

17、(k)是一条抵达答案结点的路径) then print ( X(1)X(k) );k=k+1; else k=k-1; end BACKTRACK,/回溯,/打印数组X,/考虑下一个集合,在X(1)X(k-1)已经被选定的情况下, T(X(1)X(k-1)给出X(k)的所有可能的取值,限界函数B(X(1)X(k)判断哪些X(k)满足隐式约束条件,procedure RBACKTRACK(k) global X(1:n); int k, n; for ( 满足下式的每个X(k), X(k) T(X(1)X(k-1) and B(X(1),B(k)=true) do if (X(1),X(k)是一

18、条抵达答案结点的路径 then print (X(1)X(k);call RBACKTRACK(k+1); end RBACKTRACK,回溯算法的递归描述,进入算法时, 解向量X中的前k-1个分量X(1) X(k-1)已经被赋值,一般情况下,由于回溯法在问题的解空间树上搜索问题解的过程中,利用约束条件和目标函数的界进行剪枝,避免无效搜索,因此,解空间树中每个结点未必都被访问到,而称在回溯求解过程中,访问到的所有结点对应的解空间树的子树结构为问题回溯求解的搜索树。,搜索树,6.2 8-王后问题,问题描述: 在一个8*8棋盘上放置8个王后, 使得每两个王后之间都不能互相“攻击”, 即每两个王后都

19、不能在同一行、同一列及同一条斜线上,8王后问题可以表示为8-元组(x1, , x8) ,其中xi是放置王后i所在的列号,图中的可行解表示为一个8-元组 即(4, 6, 8, 2, 7, 1, 3, 5),用二维数组A(1:8,1:8)的下标来标记每个王后的位置,那么可以看到: 对于在由左到右的同一条斜线上的每个元素具有相同的“行-列”值;对于在由右到左的同一条斜线上的每个元素则具有相同的“行+列”值,设有两个王后被放置在(i, j )和(k, l )位置上, 那么当且仅当ij = k-l 或 i+j = k+l 时, 它们才在同一条斜线上。 将这两个等式分别变换成: j-l = i- k 或

20、j-l = k- i 因此当且仅当 |j-l| = |i-k| 时( 即两个王后所在位置的行差距 等于列差距时), 两个王后在同一条斜线上,使用斜率的方法,procedure PLACE(k) int i , k; i=1; while ( ik ) do if (Xi=Xk or ABS(Xi-Xk)=ABS(i-k) thenreturn (false);i=i+1; return (true); end PLACE,若一个王后能放在第k行和第X(k)列, 则返回true, 否则返回false X是全程数组, 进入此过程时已置入了k个值, ABS是绝对值函数,判断能否放置一个新王后的算法描

21、述:,/ 若两个王后在同一列上, 或在同一对角线上, 则说明该位置不能放王后,应返回false值,求n-王后问题的回溯算法描述,procedure NQUEENS(n) int k, n, X(1:n); X1=0 ; k=1; while (k0) do Xk=Xk+1; while ( Xk=n and Not PLACE(k) ) do Xk=Xk+1; if (Xk=n) then if (k=n) then print (X);else k=k+1; Xk=0; else k=k-1; end NQUEENS,/若是一个完整的解则打印数组X,/ k是当前行; X(k)是当前列,/ 对

22、所有的行执行循环语句,/移到下一列,当该位置不能放王后时转到下一列,/找到一个位置,/否则转到下一行 (摆放下一个皇后),/回溯,0,1,PLACE(1) i=1; while ( ik ) do11 , 循环不执行 return (true);,X1=0 ; k=1; while (k0) do Xk=Xk+1; while (Xk=n and Not PLACE(k) do,1=n and Not true , 循环不执行,if (Xk=n) then if (kn) then 不执行 else k=k+1=2; X2=0; , end while,k=2; while (k0) do X

23、k=Xk+1; while ( Xk=n and Not PLACE(k) ) do,1=n and Not false , Xk=Xk+1=2;,2=n and Not false , Xk=Xk+1=3;,3=n and Not true , 循环不执行,1,2,3,if (Xk=n) then if (kn) then 不执行 else k=k+1=3; X3=0; ,0, end while,Q2,PLACE(2) i=1; while ( ik ) doif (Xi=Xk) thenreturn (false);,PLACE(2) i=1; while ( ik ) doif (|X

24、i-Xk|=|i-k|) then return (false);,PLACE(2) i=1; while ( ik ) do if (XiXk or |Xi-Xk|i-k|) then 不执行i=i+1=2; 结束循环 return (true);,k=3; while (k0) do Xk=Xk+1; while (Xk=n and Not PLACE(k) do,if (Xkn) then 不执行 else k=k-1=2; /回溯, end while,k=2; while (k0) do Xk=Xk+1=3+1=4; while ( Xk=n and Not PLACE(k) ) d

25、o,1=n and Not false , Xk=Xk+1=2;,2=n and Not false , Xk=Xk+1=3;,4=n and Not true , 循环不执行,if (Xk=n) then if (kn) then 不执行 else k=k+1=3; X3=0; , end while,Q2,1,3=n and Not false , Xk=Xk+1=4;,4=n and Not false , Xk=Xk+1=5;,2,3,4,5,4,0,5n , 循环不执行,根据回溯法的思想,上机实现n-后问题的求解过程,得出n-后问题的一个解决方案。 要求: 1)n值可由用户输入来确定

26、,如n=4,6,8。2)对确定的n,能够输出所有解决方案的总个数。,在回溯求解的基础上,考虑得到n-王后问题的所有解决方案的算法,并分析算法的时间复杂度。,作业与实验6,6.3 子集和数问题,子集和数问题: 假定有n个不同的正数, 要求找出这些数中所有使得某和数为M的组合 问题描述: 已知n+1个正数: wi (1in)和M, 要求找出wi的和数是M的所有子集 利用大小固定的元组来研究一种回溯算法,解决这一问题例: n=4 , (w1, w2, w3, w4 )=(7, 11, 13, 24) , M=31 满足要求的子集是(1, 1, 1, 0)和(1, 0, 0, 1),可变长度元组(x1

27、,x2,xk),0kn,n=4,子集和数问题的解空间树,固定长度n元组,n=4,子集和数问题的解空间树,生成图中任一结点的儿子: 对于i级上的一个结点, 其左儿子对应于X(i)=1, 右儿子对应于X(i)=0 对于限界函数的一种简单选择是:,若W(i)按升序排列, 则限界函数可以被强化:,procedure SUMOFSUB(s, k, r) global float W(1:n); global int X(1:n); float r, s; int k, j; Xk=1; if (s+Wk=M) then print(Xj, j=1 to k); print(Xj=0, j=k+1 to

28、n); return; else if (s+Wk+Wk+1=M and s+Wk+1=M) then Xk=0; call SUMOFSUB(s, k+1,r-Wk); end SUMOFSUB,子集和数问题的递归回溯算法,/生成左儿子,/若找到子集, 则打印,/ 否则当Bk=true时, 递归生成左儿子,/当Bk=true时递归生成右儿子,实例: n=6, M=30, W(1:n)=(5,10,12,13,15,18),SUMOFSUB(s, k, r),开始调用时 k=1, 由公式算出s=0, r=73 ( 注: 为书写简便将SUMOFSUB缩写为SB), SB(0, 1, 73) /s

29、=0, k=1, r=73 X1=1; if (s+Wk=M) then,0+5=530,0+5+10=1530,0+5=5,1+1=2,73-5=68,等待执行的部分: if (s+r-Wk=M and s+Wk+1=M) then Xk=0; call SB(s, k+1, r-Wk); end SB,0, 1, 73,不执行,else if (s+Wk+Wk+1=M) then,call SB(s+Wk, k+1, r-Wk);, SB(5, 2, 68) /s=5, k=2, r=68 X2=1; if (s+Wk=M) then,5+10=1530,5+10+12=2730,5+10

30、=15,2+1=3,68-10=58,等待执行的部分: if (s+r-Wk=M and s+Wk+1=M) then Xk=0; call SB(s, k+1,r-Wk); end SB,不执行,else if (s+Wk+Wk+1=M) then,call SB(s+Wk, k+1, r-Wk);,else if (s+Wk+Wk+1=M) then, SB(15, 3, 58) /s=15, k=3, r=58 X3=1; if (s+Wk=M) then,15+12=2730,15+12+13=4030,15+58-12=6130 and 15+13=2830,不执行,不执行,if (

31、s+r-Wk=M and s+Wk+1=M) then, X3=0; call SB(s, k+1,r-Wk); ,15, 3+1=4, 58-12=46,end SB, SB(15, 4, 46) /s=15, k=4, r=46 X4=1; if (s+Wk=M) then,15+13=2830,15+13+15=4330,不执行,else if (s+Wk+Wk+1=M) then,不执行,if (s+r-Wk=M and s+Wk+1=M) then, X4=0; call SB(s, k+1,r-Wk); ,15, 4+1=5, 46-13=33,end SB,15+46-13=48

32、30 and 15+15=30=30, SB(15, 3, 33) /s=15, k=5, r=33 X5=1; if (s+Wk=M) then,15+15=30=M, for j=1 to k doprint(Xj); for j=k+1 to n doprint(Xj=0); return; ,打印X=(1,1,0,0,1,0),end SB,实例: n=6, M=30,W(1:n)=(5,10,12,13,15,18),从 SB(15, 3, 33)返回到 SB(15, 4, 46), 再返回到 SB(15, 3, 58), 最后返回到 SB(5, 2, 68),执行剩余的代码, SB

33、(5, 2, 68) /s=5, k=2, r=68,5+68-10=6330 and 5+12=1730,if (s+r-Wk=M and s+Wk+1=M) then, X2=0; call SB(s, k+1,r-Wk); ,5, 2+1=3, 68-10=58,end SB,已经执行的部分: X2=1; if (s+Wk=M) then else if (s+Wk+Wk+1=M) thencall SB(s+Wk, k+1, r-Wk);,else if (s+Wk+Wk+1=M) then, SB(5, 3, 58) /s=5, k=3, r=58 X3=1; if (s+Wk=M)

34、 then,5+12=1730,5+12+13=30=30,5+12=17,3+1=4,58-12=46,等待执行的部分: if (s+r-Wk=M and s+Wk+1=M then Xk=0; call SB(s, k+1,r-Wk); end SB,不执行,call SB(s+Wk, k+1, r-Wk);, SB(17, 4, 46) /s=17, k=4, r=46 X4=1; if (s+Wk=M) then,17+13=30=M,打印X=(1,0,1,1,0,0),end SB, for j=1 to k doprint(Xj); for j=k+1 to n doprint(X

35、j=0); return; ,作业,1 对于集合P=5,7,1012,15,18,20,M=35, 试利用子集和数问题的回溯算法求取集合P的所有元素之和为M的全部子集,并画出所生成的搜索树。,2 给出n后问题的约束条件,并绘出4-王后问题的回溯求解过程中所生成的搜索树。,6.4 图的着色问题,问题描述:已知一个图G和m0种颜色, 在只准使用这m种颜色对图G的结点进行着色的情况下, 是否能使图G中任何相邻的两个结点都具有不同的颜色? 该问题称为m-着色判定问题m着色最优化问题: 求可对图G着色的最小整数m这个整数称为图G的色数。对于图着色的研究是从四色问题开始的。四色问题要求证明平面或球面上的任

36、何地图的所有区域都至多可用四种颜色来着色, 并使任何两个有一段公共边界的相邻区域没有相同的颜色,四色问题可以转换成对一平面图的4-着色判定问题地图转换为相应的平面图: 将地图的每一个区域变成一个结点, 若两个区域相邻, 则相应的结点用一条边连接起来 例: 一幅有5个区域的地图和与其对应的平面图,用图的邻接矩阵GRAPH(1:n,1:n)来表示一个图G,若(i, j)是G的一条边,则GRAPH (i, j)=true,否则GRAPH (i, j)=false,颜色用整数1, 2,m表示, 解用n-元组(X1,X2,Xn)表示, 其中Xi表示结点i 的颜色,图着色算法的解空间树是一棵度数为m, 高

37、为n+1的树在i 级上的每个结点有m个儿子, 它们与Xi的m种可能的赋值相对应(1in), 在n+1级上的结点都是叶结点。,例: 4-着色问题, n=5 , m=4,算法描述,Public class coloring Static int n, /图的顶点数 M; /可用颜色数 Static booleana; /图的邻接矩阵 Static int x; /当前解 Static long sum; /当前已找到配色方案,public static long mcoloring (int mm) m=mm; sum=0; backtrack(1); return sum; ,Private static void backtrack(int t) if (tn ) sum+; for(int i=1;in;i+) System.out.print(xi+“”); System.out.println(); else for(int i=1;im;i+)xt=i;if (ok(t) backtrack(t+1); ,Private static boolean ok(int k) /检查颜色可用性 for (int j=1;j=n;j+) if (akj ,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报