这种动态编程方法怎么样,其中C[x,y]
表示长度为不禁止的字符串的数量,x
以两个字符序列结尾y
:
C [n, 'AA'] = C[n-1, 'AA'] + C[n-1, 'AB'] + C[n-1, 'AC']
C [n, 'AB'] = C[n-1, 'BA'] + C[n-1, 'BB']
C [n, 'AC'] = C[n-1, 'CA'] + C[n-1, 'CB'] + C[n-1, 'CC']
C [n, 'BA'] = C[n-1, 'AA'] + C[n-1, 'AB'] + C[n-1, 'AC']
C [n, 'BB'] = C[n-1, 'BA'] + C[n-1, 'BB'] + C[n-1, 'BC']
C [n, 'BC'] = C[n-1, 'CA'] + C[n-1, 'CB'] + C[n-1, 'CC']
C [n, 'CA'] = C[n-1, 'AA'] + C[n-1, 'AB'] + C[n-1, 'AC']
C [n, 'CB'] = C[n-1, 'BA'] + C[n-1, 'BB'] + C[n-1, 'BC']
C [n, 'CC'] = C[n-1, 'CA'] + C[n-1, 'CB'] + C[n-1, 'CC']
有边界条件n >= 3, C[3, x] = 3, C[3, 'AB'] = 2
?
还有一个简单的程序,不确定是否正确,但肯定会冒一些被否决的风险,如果它是错误的,呵呵:)
#include <iostream>
unsigned int C[100][9];
// AA 0
// AB 1
// AC 2
// BA 3
// BB 4
// BC 5
// CA 6
// CB 7
// CC 8
void
calc (unsigned int n) {
unsigned int i;
for (i = 0; i < 9; ++i)
C[3][i] = 3;
C[3][1] = 2;
for (i = 4; i <= n; ++i) {
C[i][0] = C[i-1][0] + C[i-1][1] + C[i-1][2];
C[i][1] = C[i-1][3] + C[i-1][4];
C[i][2] = C[i-1][6] + C[i-1][7] + C[i-1][8];
C[i][3] = C[i-1][0] + C[i-1][1] + C[i-1][2];
C[i][4] = C[i-1][3] + C[i-1][4] + C[i-1][5];
C[i][5] = C[i-1][6] + C[i-1][7] + C[i-1][8];
C[i][6] = C[i-1][0] + C[i-1][1] + C[i-1][2];
C[i][7] = C[i-1][3] + C[i-1][4] + C[i-1][5];
C[i][8] = C[i-1][6] + C[i-1][7] + C[i-1][8];
}
}
// C [n, 'AA'] = C[n-1, 'AA'] + C[n-1, 'AB'] + C[n-1,'AC']
// C [n, 'AB'] = C[n-1, 'BA'] + C[n-1, 'BB']
// C [n, 'AC'] = C[n-1, 'CA'] + C[n-1, 'CB'] + C[n-1, 'CC']
// C [n, 'BA'] = C[n-1, 'AA'] + C[n-1, 'AB'] + C[n-1, 'AC']
// C [n, 'BB'] = C[n-1, 'BA'] + C[n-1, 'BB'] + C[n-1, 'BC']
// C [n, 'BC'] = C[n-1, 'CA'] + C[n-1, 'CB'] + C[n-1, 'CC']
// C [n, 'CA'] = C[n-1, 'AA'] + C[n-1, 'AB'] + C[n-1, 'AC']
// C [n, 'CB'] = C[n-1, 'BA'] + C[n-1, 'BB'] + C[n-1, 'BC']
// C [n, 'CC'] = C[n-1, 'CA'] + C[n-1, 'CB'] + C[n-1, 'CC']
int
main () {
for (unsigned int i = 3; i < 10; ++i) {
calc (i);
unsigned int s = 0;
for (unsigned int j = 0; j < 9; ++j)
s += C[i][j];
std::cout << s << " ";
}
}