动态规划之Edit Step Ladders

题目:

An edit step is a transformation from one word x to another word y such that x and y are words in the dictionary, and x can be transformed to y by adding, deleting, or changing one letter. So the transformation from dig to dog or from dog to do are both edit steps. An edit step ladder is a lexicographically ordered sequence of words w1,w2,...,wn such that the transformation from wi to wi+1 is an edit step for all i from 1 to n−1. For a given dictionary, you are to compute the length of the longest edit step ladder.
Input
The input to your program consists of the dictionary – a set of lower case words in lexicographic order – one per line. No word exceeds 16 letters and there are no more than 25000 words in the dictionary.
Output
The output consists of a single integer, the number of words in the longest edit step ladder.

Sample Input
cat

dig

dog

fig

fin

fine

fog

log

wine
Sample Output
5

动态规划很好想,就是在判断的时候先把一个词所有可能的变换找出来,然后由于单词有序可以二分查找,否则一个一个去比会超时...这道题因为变换的时候末尾没加\0,wa了超多次..郁闷死我了....大致思路是这样,其中还有一些点应该还可以优化....啊我去,先不管了...

#include<stdio.h>
#include<string.h>
char word[25000][20];
int dp[25000];
int find(int r,char target[]){
    int l,mid,flag;
    l=0;
    while(l<=r){
        mid=(l+r)/2;
        flag=strcmp(word[mid],target);
        if(flag==0)
            return mid;
        else if(flag>0)
            r=mid-1;
        else
            l=mid+1;
    }
    return -1;
}
int change(int pos,char t[],int i,char c){
    strcpy(t,word[i]);
    t[pos]=c;
    return find(i-1,t);
}
int del(int pos,char t[],int i){
    int k,j=0;
    for(k=0;k<strlen(word[i]);k++){
        if(pos==k)
            continue;
        t[j]=word[i][k];
        j++;
    }
    t[j]='\0';
    return find(i-1,t);
}
int add(int pos,char t[],int j,char c){
    int i;
    strcpy(t,word[j]);
    t[pos]=c;
    for(i=pos;i<strlen(word[j]);i++)
        t[i+1]=word[j][i];
    t[strlen(word[j])+1]='\0';
    return find(j-1,t);
}
int main(){
    int n=0;
    int i,pos,index,tmp,ans;
    char c;
    char t[30];
    while(scanf("%s",word[n])!=EOF)
        n++;
    dp[0]=ans=1;
    for(i=1;i<n;i++){
        tmp=0;
        for(c='a';c<'a'+26;c++){
            for(pos=0;pos<=strlen(word[i]);pos++){
                index=add(pos,t,i,c);
                if(index>=0&&dp[index]>tmp)
                    tmp=dp[index];
            }
            for(pos=0;pos<strlen(word[i]);pos++){
                index=change(pos,t,i,c);
                if(index>=0&&dp[index]>tmp)
                    tmp=dp[index];
            }
        }
        for(pos=0;pos<strlen(word[i]);pos++){
            index=del(pos,t,i);
            if(index>=0&&dp[index]>tmp)
                tmp=dp[index];
        }
        dp[i]=tmp+1;
        if(dp[i]>ans)
            ans=dp[i];
    }
    printf("%d\n",ans);
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值