HDU 5510 Bazinga(思维)

来源:互联网 发布:linux 通配符 编辑:程序博客网 时间:2024/06/05 08:38

题目大意:给你n个字符串,要求你找出符合1 < j <= n,且存在i < j,且i不是j的子集的最大的j

解题思路:这题我用dp将其相同的压缩起来,接着再从前往后找了一下

#include <cstdio>#include <cstring>const int N = 510;const int M = 2010;int next[N][M], len[N], dp[N];char str[N][M];int n, cas = 1; void init() {    scanf("%d", &n);    for (int i = 1; i <= n; i++) {        scanf("%s", str[i]);        len[i] = strlen(str[i]);    }}void getNext(int cur) {    int i = 0, j = -1;    next[cur][0] = -1;    while (i < len[cur]) {        if (j == -1 || str[cur][i] == str[cur][j]) {            i++; j++;            next[cur][i] = j;        }        else j = next[cur][j];    }}void solve() {    for (int i = 1; i <= n; i++)        getNext(i);    memset(dp, -1, sizeof(dp));    dp[1] = 1;    for (int i = 2; i <= n; i++) {        bool flag = false;        for (int j = i - 1; j ; j = dp[j] - 1) {            bool ok = false;            int k = 0, l = 0;            while (l < len[i]) {                if (k == -1 || str[j][k] == str[i][l]) {                    k++; l++;                    if (k == len[j]) {                        flag = ok = true;                        dp[i] = dp[j];                        break;                    }                 }                else k = next[j][k];            }            if (!ok) break;        }        if (!flag) dp[i] = i;    }    for (int i = n; i >= 1; i--) {        if (dp[i] != 1) {            printf("Case #%d: %d\n", cas++, i);            return ;        }    }    printf("Case #%d: %d\n", cas++, -1);}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();        solve();    }    return 0;}
0 0
原创粉丝点击