主要记录一些启发式搜索,状态空间搜索,状态机搜索等

字符串状态机搜索(简单)

HDU4051
HDU4051
HDU4051

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
const int maxn = 5, slen = 500;
char str[slen];
int lim[maxn], n, LEN;

int tlen[maxn], l[maxn], sub[maxn][maxn];

int st[maxn];
bool check() {
int vis[maxn];
memset(vis, 0, sizeof(vis));
vis[n-1] = 1, st[n-1] = 0;

for (int i = n-1; i >= 1; i--) {
int p = st[i];

// p follow the substring of string i
for (int j = 0; j < l[i]; j++) {
int id = sub[i][j];
if (id == -1) p++;
else {
if (!vis[id]) { vis[id] = true; st[id] = p; }
else {
for (int d = 0; d < tlen[id]; d++) {
if (str[p+d] != str[ st[id]+d ]) return false;
}
}
p += tlen[id];
}
}
}
return true;
}

bool h(int cur, int maxll) {
int t = maxll;
for (int i = cur; i < n; i++) t *= lim[i];
if (t < LEN) return false;
return true;
}

bool dfs(int cur, int len, int k, int maxll) {
if (h(cur, maxll) == false) return false;

if (cur == n) {
// check valid
return tlen[n-1] == LEN && check();
}

if (k && k == l[cur]) {
// substr cur is finished, get tlen
tlen[cur] = 0;
for (int i = 0; i < l[cur]; i++) {
int id = sub[cur][i];
tlen[cur] += (id == -1 ? 1 : tlen[id]);
}
return dfs(cur+1, 0, 0, max(maxll, tlen[cur]));
}

if (len == 0) {
// enumerate length of substr cur
for (int i = lim[cur]; i >= 1; i--) {
l[cur] = i;
if (dfs(cur, i, 0, maxll)) return true;
}
}
else {
// enumerate sub(cur, k)
for (int i = cur-1; i >= -1; i--) {
sub[cur][k] = i;
if (dfs(cur, len, k+1, maxll)) return true;
}
}
return false;
}

void init() {
memset(tlen, 0, sizeof(tlen));
memset(l, 0, sizeof(l));
memset(sub, 0, sizeof(sub));
memset(st, 0, sizeof(st));
}

int main() {
freopen("input.txt", "r", stdin);
while (scanf("%d", &n) != EOF) {
init();

// get data
for (int i = n-1; i >= 0; i--) scanf("%d", &lim[i]);
scanf("%s", str);
LEN = strlen(str);
reverse(str, str + LEN);

// then dfs
int ans = dfs(0, 0, 0, 1);
if (ans) printf("Yes\n");
else printf("No\n");
}
}