zoukankan      html  css  js  c++  java
  • HDU 6170 Two strings 思维 DP

      题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6170

      题目描述: 两个字符串问是否匹配, '.'可以匹配任意字符, '*'可以使前一个数的出现次数成上一个自然数(0, 1, 2, 3........)

      解题思路: DP, dp(i, j)表示A串匹配到j位, B串匹配到i位两个串是否匹配, 转移方程再代码里有, 参考Jaihk662的博客, 注释在代码中

      代码:

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <iterator>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <deque>
    #include <map>
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    #define mem0(a) memset(a,0,sizeof(a))
    #define meminf(a) memset(a,-0x3f,sizeof(a))
    #define fi(n) for(i=0;i<n;i++)
    #define fj(m) for(j=0;j<m;j++)
    #define sca(x) scanf("%d",&x)
    #define ssca(x) scanf("%s",x)
    #define scalld(x) scanf("%I64d",&x)
    #define print(x) printf("%d
    ", x)
    #define printlld(x) printf("%I64d
    ",x)
    #define de printf("=======
    ")
    #define yes printf("YES
    ")
    #define no printf("NO
    ")
    typedef long long ll;
    using namespace std;
    
    const int maxn = 2600;
    char a[maxn];
    char b[maxn];
    int dp[maxn][maxn]; // dp[i][j] 表示 b串匹配到了第i个,a串匹配到了第j个时, 是否匹配
    
    int main() {
        int t;
        sca( t );
        while( t-- ) {
            mem0(dp);
            ssca(a+1);
            ssca(b+1);
            int la = (int)strlen(a+1);
            int lb = (int)strlen(b+1);
            dp[0][0] = 1;
            if( b[2] == '*' ) dp[2][0] = 1; //初始化
            for( int i = 1; i <= lb; i++ ) {
                for( int j = 1; j <= la; j++ ) {
                    if( b[i] == '.' ) { // 如果当前位是'.'或者相等就直接转移
                        dp[i][j] = max(dp[i][j], dp[i-1][j-1] );
                    }
                    else if( b[i] != '*' ){
                        if( b[i] == a[j] ) {
                            dp[i][j] = max(dp[i][j], dp[i-1][j-1] );
                        }
                    }
                    else { //当前是'*'
                        dp[i][j] = max( dp[i-1][j], dp[i-2][j] );
                        if( (dp[i-1][j-1] || dp[i][j-1]) && a[j] == a[j-1] ) { /*如果前一位匹配上一位已经匹配或者本位已经匹配 且a串的前后相邻两个字符相等, 主要解决aaaaaaaaaaaaa 和 a* 的这种情况*/
                            dp[i][j] = max( dp[i][j], max(dp[i-1][j-1], dp[i][j-1]) );
                        }
                    }
                }
            }
            if( dp[lb][la] ) {
                printf( "yes
    " );
            }
            else {
                printf( "no
    " );
            }
        }
        return 0;
    }
    View Code

      思考: 一开始想枚举直接判断了, 结果很快就WA了,越到后面越复杂,  心不细就不要枚举......我没想到这道题也能用DP做, 真的是长见识了, 看来对于DP still have a long way to go  啊...... 感觉暑假快结束了, 自己到底有没有提高呢

  • 相关阅读:
    c#可以做什么
    C#是否快被年代所筛选?
    在.NET程序中,C#办法可用来封装代码
    关于程序员的小故事
    码农需了解的代码编写标准
    关于HTML代码的技巧
    分析一波编程语言的前景
    彻底解决Linux索引节点(inode)占用率高的告警
    Python29之字符str与字节bytes
    Python28之文件1
  • 原文地址:https://www.cnblogs.com/FriskyPuppy/p/7413871.html
Copyright © 2011-2022 走看看