zoukankan      html  css  js  c++  java
  • UVA 10029 Edit Step Ladders

    UVA_10029

        这个题目一开始想转化成最长上升子序列的模型,但发现这样不好做,后来看了别人的题解发现可以转化成找有向无环图的最长路去做。

        这样面临的一个问题就是如果显性地建图的话是没办法存下每条边的,于是我们不妨在每次尝试连线的时候再判断这条边是否存在。

        为了方便判断两个字符串之间是否有一条有向边,我们不妨以起点为基础,施加3种变换,观察是否可以变换出字典里的字符串,如果可以变换出的话,就说明这两个字符串之间存在一条有向边。

        对于判断是否可以变换出字典里的字符串这一步,可以用哈希表也可以二分查找字典。找最长路的过程可以采用记忆化搜索的方式。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 25010
    #define HASH 1000003
    int N, head[HASH], next[MAXD], f[MAXD];
    char b[MAXD][20], temp[20];
    int hash(char *str)
    {
    int v = 0, seed = 131;
    while(*str)
    v = v * seed + *(str ++);
    return (v & 0x7fffffff) % HASH;
    }
    void insert(int s)
    {
    int i, h;
    h = hash(b[s]);
    next[s] = head[h];
    head[h] = s;
    }
    int search()
    {
    int i, h;
    h = hash(temp);
    for(i = head[h]; i != -1; i = next[i])
    if(strcmp(b[i], temp) == 0)
    break;
    return i;
    }
    void init()
    {
    N = 0;
    memset(head, -1, sizeof(head));
    while(scanf("%s", b[N]) == 1)
    {
    insert(N);
    N ++;
    }
    }
    void add(int s, int st, int k)
    {
    int i, j;
    for(i = 0, j = 0; i < st; i ++, j ++)
    temp[j] = b[s][i];
    temp[j ++] = 'a' + k;
    for(; b[s][i]; i ++, j ++)
    temp[j] = b[s][i];
    temp[j] = '\0';
    }
    void del(int s, int st)
    {
    int i, j;
    for(i = 0, j = 0; i < st; i ++, j ++)
    temp[j] = b[s][i];
    i ++;
    for(; b[s][i]; i ++, j ++)
    temp[j] = b[s][i];
    temp[j] = '\0';
    }
    void change(int s, int st, int k)
    {
    strcpy(temp, b[s]);
    temp[st] = 'a' + k;
    }
    int dp(int cur)
    {
    int i, j, k, st, len, s, t, max;
    if(f[cur] != -1)
    return f[cur];
    max = 0;
    len = strlen(b[cur]);
    for(st = 0; st <= len; st ++)
    for(k = 0; k < 26; k ++)
    {
    add(cur, st, k);
    s = search();
    if(s != -1 && strcmp(b[cur], temp) < 0)
    {
    t = dp(s);
    if(t + 1 > max)
    max = t + 1;
    }
    }
    for(st = 0; st < len; st ++)
    {
    del(cur, st);
    s = search();
    if(s != -1 && strcmp(b[cur], temp) < 0)
    {
    t = dp(s);
    if(t + 1 > max)
    max = t + 1;
    }
    }
    for(st = 0; st < len; st ++)
    for(k = 0; k < 26; k ++)
    {
    change(cur, st, k);
    s = search();
    if(s != -1 && strcmp(b[cur], temp) < 0)
    {
    t = dp(s);
    if(t + 1 > max)
    max = t + 1;
    }
    }
    return f[cur] = max;
    }
    void solve()
    {
    int i, t, max = 0;
    memset(f, -1, sizeof(f));
    for(i = 0; i < N; i ++)
    {
    t = dp(i);
    if(t > max)
    max = t;
    }
    printf("%d\n", max + 1);
    }
    int main()
    {
    init();
    solve();
    return 0;
    }


  • 相关阅读:
    Java线程状态及Thread类中的主要方法
    Kali Linux 装好系统后安装经常使用软件
    Setup SSH and SVN on Windows Server
    sql plus 抢救数据(測)
    利用用户自己的server、tomcat下的解决iOS7.1企业应用无法安装应用程序 由于证书无效的问题
    mysql基本操作【重要】
    Mybatis逆向工程——(十四)
    lucene查询索引之QueryParser解析查询——(八)
    lucene查询索引之Query子类查询——(七)
    lucene修改索引——(六)
  • 原文地址:https://www.cnblogs.com/staginner/p/2269222.html
Copyright © 2011-2022 走看看