给定一组12个随机挑选的多米诺骨牌,我需要找到最长的多米诺骨牌链。我已经递归地生成了所有多米诺骨牌的可能性(使用0到12的面值有91种可能性)。一个多米诺骨牌由一个带有两个正方形的“砖”组成:[a | b]其中0 =
多米诺骨牌可以翻转以容纳比赛。例如,给定[8,4],[9,4]可以翻转成对[8,4] [4,9]
以下(与该问题相关)方法可用于此类:
void flipEnds(); // Flips the domino
int getLeft() const;
int getRight() const;
bool hasBeenPlayed() const;
void setPlayed(bool value);
因此,此问题的样本数据如下:
myDomino #0: [1 12 ]
myDomino #1: [0 5 ]
myDomino #2: [7 9 ]
myDomino #3: [2 7 ]
myDomino #4: [7 12 ]
myDomino #5: [4 8 ]
myDomino #6: [8 10 ]
myDomino #7: [3 11 ]
myDomino #8: [11 12 ]
myDomino #9: [10 11 ]
myDomino #10: [2 9 ]
myDomino #11: [2 4 ]
这更多是一个数学问题,但是如何找到最长的多米诺骨牌链呢?我认为它必须递归完成。
最佳答案
多米诺骨牌序列可以表示为{#3,Y},{#4,N},{#0,Y},... ...第一个数字是您手中的多米诺骨牌号码,第二个数字是是否是否翻转。我们想检查所有可能的顺序,但是很早就删节显然是非法的。
假设您有一个testSequence(sequence)
函数,该函数测试一个序列是否有效。
保留两个列表,一个是当前序列currentSeq
,另一个是您尚未选择unused
的多米诺骨牌。
递归可能像
checkAllSeq( currentSeq, unused ) {
foreach( domino in unused ) {
unused2 = unused - domino // remove domino from unused list
seq1 = currentSeq + {domino,true} // add unfliped domino to sequence to test
if( testSequence(seq1) ) {
checkAllSeq(seq1,unused2) // recurse
}
// now do it with the domino flipped
seq2 = currentSeq + {domino,false}
if( testSequence(seq2) ) {
checkAllSeq(seq2,unused2)
}
}
}
我错过了几件事。这只是测试所有可能的序列,它对结果没有任何作用。