hdu 5311 Hidden String(dp+暴力dfs)

来源:互联网 发布:手机cad软件下载 编辑:程序博客网 时间:2024/05/18 18:01

题目链接:

点击打开链接

题目大意:

给出一个字符串,问能否拆出三个不重叠的字串然后连接在一起凑成anniversary。

题目分析:

给出的串我们设为s,模式匹配串我们设为p,设dp[i][j]为当前串以第i个字符结尾模式串以j个字符结尾能够匹配的最大的长度。

那么如果s[i] == p[j] , 那么dp[i][j] = dp[i-1][j-1] + 1

否则dp[i][j] = 0;

那么之后我们直接暴力求解即可。

就是找到每次切割的字符串的点,然后利用dp[i][j]判断当前切割方法能否保证能够完全覆盖p串,然后判断是否是切割出了三个串,如果是的话那么就是能够切割,否则就是不能。枚举所有情况

代码如下:

#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>using namespace std;int t,n,m;char p[]="anniversary";char s[107];int dp[107][107];bool flag;void dfs ( int i , int j , int cnt ){    //cout << i <<" " << j << " " << cnt<< endl;    if ( flag ) return;    if ( j == m-1 )    {        if ( cnt != 3 ) return;        flag = true;        return;    }    for ( int k = i+1 ; k < n ; k++ )        for ( int l = j+1 ; l < m ; l++ )        {            if ( j+dp[k][l] >= l && i+(l-j) <= k )            {                dfs ( k , l , cnt+1);            }        }}int main ( ){    scanf ( "%d" , &t );    while ( t-- )    {        scanf ( "%s" , s );        n = strlen ( s );        m = strlen ( p );        memset ( dp , 0 , sizeof ( dp ));        for ( int i = 0 ; i < n ; i++ )            for ( int j = 0 ; j < m ; j++ )                if ( s[i] == p[j] )                {                    if ( i == 0 || j == 0 )                        dp[i][j] = 1;                    else                        dp[i][j] = dp[i-1][j-1] + 1;                }        flag = false;        dfs ( -1 , -1 , 0 );        if ( flag ) puts ( "YES" );        else puts ( "NO" );    }}


0 0
原创粉丝点击