[tyvj1170]0/1字符串问题
描述
编程找出符合下列条件的字符串:①字符串中仅包含0和1两个字符;②字符串的长度为n;③字符串中不含有三个连续的相同子串。
输入格式
输入文件仅包含一个整数n(0<n≤35),表示字符串的长度。
输出格式
输出文件仅包含一个整数,表示符合上述条件的字符串的总数。
测试样例1
输入
2
输出
4
备注
各个测试点1s
我写的裸的搜索1S过去不,所以原来n<=40改成了n<=35,如果你有更好的算法,请发站内消息联系我!
我写的裸的搜索1S过去不,所以原来n<=40改成了n<=35,如果你有更好的算法,请发站内消息联系我!
分析
dfs+一点优化。第一个数字确定之后只要搜一遍,再把结果乘以2即可(01相互反转可以得到一个新的01串)。每次搜索时判断一下是否会出现连续子串,暴力即可AC。
代码
1 #include <iostream> 2 using namespace std; 3 int A[50]; 4 int n, tot; 5 bool can(int i) 6 { 7 bool flag_1 = true; 8 for (int l = 1; l <= (i + 1) / 3 && flag_1; ++l) { 9 bool flag_2 = true; 10 for (int j = i; j > i - l && j - 2 * l >= 0 && flag_2; --j) { 11 if (A[j] != A[j - l] || A[j] != A[j - l * 2] || A[j - l] != A[j - l * 2]) 12 flag_2 = false; 13 } 14 flag_1 = !flag_2; 15 } 16 return flag_1; 17 } 18 void dfs(int i) 19 { 20 if (i == n) 21 ++tot; 22 else { 23 A[i] = 0; 24 if (can(i)) 25 dfs(i + 1); 26 A[i] = 1; 27 if (can(i)) 28 dfs(i + 1); 29 } 30 } 31 int main() 32 { 33 34 cin >> n; 35 dfs(1); 36 tot *= 2; 37 cout << tot; 38 return 0; 39 }