码迷,mamicode.com
首页 > 编程语言 > 详细

hdu 5311 Hidden String dp o(n)算法 深搜

时间:2015-07-27 13:17:24      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:

Hidden String

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 857    Accepted Submission(s): 322


Problem Description
Today is the 1st anniversary of BestCoder. Soda, the contest manager, gets a string s技术分享 of length n技术分享. He wants to find three nonoverlapping substrings s[l技术分享1技术分享..r技术分享1技术分享]技术分享, s[l技术分享2技术分享..r技术分享2技术分享]技术分享, s[l技术分享3技术分享..r技术分享3技术分享]技术分享 that:

1. 1l技术分享1技术分享r技术分享1技术分享<l技术分享2技术分享r技术分享2技术分享<l技术分享3技术分享r技术分享3技术分享n技术分享

2. The concatenation of s[l技术分享1技术分享..r技术分享1技术分享]技术分享, s[l技术分享2技术分享..r技术分享2技术分享]技术分享, s[l技术分享3技术分享..r技术分享3技术分享]技术分享 is "anniversary".
 

Input
There are multiple test cases. The first line of input contains an integer T技术分享 (1T100)技术分享, indicating the number of test cases. For each test case:

There‘s a line containing a string s技术分享 (1|s|100)技术分享 consisting of lowercase English letters.
 

Output
For each test case, output "YES" (without the quotes) if Soda can find such thress substrings, otherwise output "NO" (without the quotes).
 

Sample Input
2 annivddfdersewwefary nniversarya
 

题意,就是给一段字符串,要求找出目标串,且最多只能三个片段串。

由于s很小,所以用深搜,暴力乱搞就好了。但这里用dp也能解决。复杂度是o(n)

定义pre[i][j] 表示字符串第i个位置,从目标串往后能匹配pre[i][j] 个,也就是说s(i,i+pre[i][j] ) == g(j,j+pre[i][j] ) g表示目标串。

则pre[i][j] 转状转移很简单就是pre[i+1][j+1]转移来就可以了。

定义dp[i][j]表示,字符串第i-1个位置前已经匹配到了目标串g的第j-1个位置且已用的分段数就是dp[i][j]。则状态转移方程就是

dp[i][j]可以从dp[i-1][j]得来,也可以转移到dp[i+pre[i][j]][j+pre[i][j]],取分段数的最小值。

答案只要dp[s][11]大于1,说明存在。

由于本题目标串g的长度为定值,所以复杂度为o(s * 11)线性算法,如果,改变一下,g不是字长,而是变长的,那么复杂度则为o(s* g)了,与分段数是无关的。

#define N 205
#define M 100005
#define maxn 205
#define MOD 1000000000000000007
int n,glen,len,dp[N][12],pre[N][11];
char str[N];
char goal[20] = "anniversary";
void Update(int & a,int b){
    if(a == 0) a = b;
    else a = min(a,b);
}
int main()
{
    glen = strlen(goal);
    while(S(n)!=EOF)
    {
        while(n--){
            SS(str);len = strlen(str);
            FI(len){
                FJ(11){
                    if(str[i] == goal[j]) pre[i][j] = 1;
                    else pre[i][j] = 0;
                }
            }
            for(int i = len - 2;i>=0;i--){
                FJ(10){
                    if(pre[i][j] && pre[i+1][j+1]) pre[i][j] = pre[i+1][j+1] + 1;
                }
            }
            fill(dp,0);
            for(int i = 0;i<len;i++){
                FJ(11){
                    if(i && dp[i-1][j])   Update(dp[i][j],dp[i-1][j]);
                    if((dp[i][j] || !j )&&dp[i][j] < 3 && pre[i][j]){
                     Update(dp[i+pre[i][j]][j+pre[i][j]],dp[i][j] + 1);
                    }
                }
            }
            bool flag = true;
            for(int i = 0;i<=len && flag;i++){
                if(dp[i][11]) flag = false;
            }
            if(!flag)
                printf("YES\n");
            else
                printf("NO\n");
        }
    }
    return 0;
}

再给个用深搜暴力解决的,更简单,更好理解,也好写,在比赛的时候,抢时间,也能有用处,但复杂度就很高了。

#define N 205
#define M 100005
#define maxn 205
#define MOD 1000000000000000007
int n,glen,len;
char str[N];
char goal[20] = "anniversary";
bool DFS(int si,int gi,int num){
    if(num <=3 && gi >= glen) return true;
    if(num > 3) return false;
    for(int i = si;i<len;i++){
        int ti = i,tgi = gi;
        while(ti<len && tgi < glen && str[ti] == goal[tgi]) tgi++,ti++;
        if(ti > i && DFS(ti,tgi,num + 1)) return true;
    }
    return false;
}
int main()
{
    glen = strlen(goal);
    while(S(n)!=EOF)
    {
        while(n--){
            SS(str);len = strlen(str);
            if(DFS(0,0,0))
            printf("YES\n");
            else
            printf("NO\n");
        }
    }
    return 0;
}


Sample Output
YES NO
 

Source
 

Recommend
hujie   |   We have carefully selected several similar problems for you:  5315 5314 5312 5310 5309 

版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu 5311 Hidden String dp o(n)算法 深搜

标签:

原文地址:http://blog.csdn.net/mengzhengnan/article/details/47082301

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!