1051 - Good or Bad DFS 记忆化搜索
http://lightoj.com/volume_showproblem.php?problem=1051
对于每个位置,设dfs(cur, one, two)表示前i个字母,拥有辅音字母one个,元音字母two个的情况。
目标是使得cur移动到结尾,这样就是能产生good串。然后超时
记忆化搜索。
比如前面的字符串是
JFLKAJS??FHJADJFA?
我不管前面的问号变了什么,也不管前面的东西是什么情况,假如,假如我的最后一个问号是变了元音,那么它下一个状态肯定
就是dfs(cur + 1, 0, two + 1),也就是辅音变成了0个。这样会使得很多状态重复了。所以记录一下就好。
JFLKAJS??FHJADJFA ? JFIJIJASLH??SDUAFHK??,也就是考虑现在空格分开的那个问号,假如我是把它变了元音,
它的连续的元音是2个,辅音是0个,这是固定了的状态了,如果搜索过的话,后面的已经不用枚举了。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> #include <bitset> bool is[222]; int dp[50 + 2][50 + 2][50 + 2]; int DFN, lenstr; char str[222]; bool good, bad; void dfs(int cur, int one, int two) { if (dp[cur][one][two] == DFN) return; dp[cur][one][two] = DFN; if (bad && good) return; if (one == 5 || two == 3) { bad = true; return; } if (cur == lenstr + 1) { good = true; return; } if (str[cur] == '?') { dfs(cur + 1, one + 1, 0); dfs(cur + 1, 0, two + 1); } else { if (is[str[cur]]) { dfs(cur + 1, 0, two + 1); } else dfs(cur + 1, one + 1, 0); } } void work() { scanf("%s", str + 1); lenstr = strlen(str + 1); ++DFN; good = false, bad = false; dfs(1, 0, 0); static int f = 0; if (good && bad) { printf("Case %d: MIXED\n", ++f); } else if (bad) { printf("Case %d: BAD\n", ++f); } else { printf("Case %d: GOOD\n", ++f); } } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif is['A'] = is['E'] = is['I'] = is['O'] = is['U'] = true; int t; scanf("%d", &t); while (t--) work(); return 0; }
既然选择了远方,就要风雨兼程~
posted on 2017-02-19 22:20 stupid_one 阅读(152) 评论(0) 编辑 收藏 举报