zoukankan      html  css  js  c++  java
  • UVa 10029 Edit Step Ladders(hash状态压缩DP)

    题意:

    给定多个字符串,是按照字典顺序排列的。一个字符串如果能够可以通过改变一个字母,删除一个字母,增加一个字母变成后面的某一个字符串,

    那么称这两个字符串之间存在一个阶梯,问最多有多少个阶梯。

    思路:

    http://www.cnblogs.com/staginner/archive/2011/11/30/2269222.html

    这一题的难点在于题目数据量很大,O(n^2)的算法铁定会超时。另类的解题思路是:构造一个hash表,把给定的字符串都存进去。

    然后试图对每个字符串进行删除,插入,修改等操作,查询经过变换后的字符串是否在hash表中,并且这个变换后的字符串要在源字符串的后面。

    然后记忆化搜索得出最长的阶梯。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    
    const int MAXN = 25010;
    const int HASH = 1000010;
    int n, head[HASH], next[MAXN], f[MAXN];
    char b[MAXN][20], temp[20];
    
    int hash(const char *s)
    {
        int v = 0, seed = 131;
        while (*s)
            v = v * seed + *(s++);
        return (v & 0x7fffffff) % HASH;
    }
    
    void insert(int s)
    {
        int h = hash(b[s]);
        next[s] = head[h];
        head[h] = s;
    }
    
    int search(const char *s)
    {
        int i, h = hash(s);
        for (i = head[h]; i != -1; i = next[i])
            if (!strcmp(b[i], s))
                break;
        return i;
    }
    
    void add(const char *s, int p, int d)
    {
        int i = 0, j = 0;
    
        while (i < p)
            temp[j++] = s[i++];
    
        temp[j++] = 'a' + d;
    
        while (s[i])
            temp[j++] = s[i++];
    
        temp[j] = '\0';
    }
    
    void del(const char *s, int p)
    {
        int i = 0, j = 0;
    
        while (i < p)
            temp[j++] = s[i++];
    
        ++i;
    
        while (s[i])
            temp[j++] = s[i++];
    
        temp[j] = '\0';
    }
    
    void change(const char *s, int p, int d)
    {
        strcpy(temp, s);
        temp[p] = 'a' + d;
    }
    
    int dp(int s)
    {
        if (f[s] != -1)
            return f[s];
    
        int ans = 0;
        int len = strlen(b[s]);
    
        for (int p = 0; p <= len; ++p)
        {
            for (int d = 0; d < 26; ++d)
            {
                add(b[s], p, d);
                int v = search(temp);
                if (v != -1 && strcmp(b[s], temp) < 0)
                {
                    int t = dp(v);
                    if (ans < t + 1)
                        ans = t + 1;
                }
            }
        }
    
        for (int p = 0; p < len; ++p)
        {
            del(b[s], p);
            int v = search(temp);
            if (v != -1 && strcmp(b[s], temp) < 0)
            {
                int t = dp(v);
                if (ans < t + 1)
                    ans = t + 1;
            }
        }
    
        for (int p = 0; p < len; ++p)
        {
            for (int d = 0; d < 26; ++d)
            {
                change(b[s], p, d);
                int v = search(temp);
                if (v != -1 && strcmp(b[s], temp) < 0)
                {
                    int t = dp(v);
                    if (ans < t + 1)
                        ans = t + 1;
                }
            }
        }
        return f[s] = ans;
    }  
    
    void solve()
    {
        memset(f, -1, sizeof(f));
        int ans = 0;
        for (int i = 0; i < n; ++i)
        {
            int t = dp(i);
            if (ans < t)
                ans = t;
        }
        printf("%d\n", ans + 1);
    }
    
    void init()
    {
        n = 0;
        memset(head, -1, sizeof(head));
    
        while (scanf("%s", b[n]) == 1)
        {
            insert(n), ++n;
        }
    }
    
    int main()
    {
        init();
        solve();
        return 0;
    }

     

    -------------------------------------------------------

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

    -------------------------------------------------------

  • 相关阅读:
    mybatis :xml文件中传入参数和if标签结合使用时要点
    mysql:查询数据库版本的几种方式
    http post 方法传递参数的2种方式
    深入理解mybatis参数
    Mybatis:动态sql
    Mybatis:传入参数方式以及#{}与${}的区别
    [GLSL]着色器周记02——火焰特效 【转】
    OpenGL ES入门09-GLSL实现常见特效 [转]
    RenderMonkey 练习 第五天 【OpenGL NormalMapping】
    反射向量 及 向量投影
  • 原文地址:https://www.cnblogs.com/kedebug/p/2780846.html
Copyright © 2011-2022 走看看