zoukankan      html  css  js  c++  java
  • UVA 10029 Edit Step Ladders ——(DAG求最长路)

      题意:升序的给出一本若干个单词,每个单词都可删除一个字母,添加一个字母或者改变一个字母,如果任意一个操作以后能变成另外一个字典中的单词,那么就连一条有向边,求最长的长度。

      分析:DAG的最长路和最短路在算法竞赛入门里边原原本本有的,结果我现在忘记了,,真是太弱了。。方法就是,用map对应键值(以建图),然后删除操作和修改操作可以看做同一个操作,之后每个操作都是在相应的位置添加一个 '*' 就可以了。想说的有两点,一个是为什么删除和修改可以看做一个操作,其实删除这个操作根本就是多余的,因为一个单词比方说add要和ad匹配,不一定要add删除,而是可以ad添加一个d,所以说删除操作是多余的;第二点是添加操作时,要注意两头都是可以放 '*' 的。

      建完图以后用求DAG的最长路的方法进行dp即可。

      具体见代码:

     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <string.h>
     4 #include <string>
     5 #include <map>
     6 #include <vector>
     7 #include <iostream>
     8 using namespace std;
     9 const int N = 25000+5;
    10 
    11 string s[N];
    12 vector<int> G[N];
    13 map<string,int> M;
    14 int dp[N];
    15 
    16 string change(string s,int pos) //删除操作和改变操作可以看做是一样的
    17 {
    18     string ans = "";
    19     for(int i=0;i<s.size();i++)
    20     {
    21         if(pos == i) ans += '*';
    22         else ans += s[i];
    23     }
    24     return ans;
    25 }
    26 
    27 string add(string s,int pos)
    28 {
    29     string ans = "";
    30     for(int i=0;i<s.size();i++)
    31     {
    32         if(pos == i) ans += '*';
    33         ans += s[i];
    34     }
    35     if(pos == s.size()) ans += '*';
    36     return ans;
    37 }
    38 
    39 int dfs(int x)   //dfs求DAG的最长边
    40 {
    41     if(dp[x] != -1) return dp[x];
    42     int ans = 0;
    43     for(int i=0;i<G[x].size();i++)
    44     {
    45         int v = G[x][i];
    46         ans = max(ans,dfs(v));
    47     }
    48     return dp[x] = ans + 1;
    49 }
    50 
    51 int main()
    52 {
    53     int cnt = 0;
    54     while(cin>>s[cnt++]);
    55 
    56     for(int i=0;i<cnt;i++)
    57     {
    58         for(int j=0;j<s[i].size();j++)
    59         {
    60             string t = change(s[i],j);
    61             if(M.count(t))
    62             {
    63                 G[M[t]].push_back(i);
    64             }
    65             M[t] = i;
    66         }
    67 
    68         for(int j=0;j<=s[i].size();j++)
    69         {
    70             string t = add(s[i],j);
    71             if(M.count(t))
    72             {
    73                 G[M[t]].push_back(i);
    74             }
    75             M[t]=i;
    76         }
    77     }
    78 
    79     memset(dp,-1,sizeof(dp));
    80     int ans = 0;
    81     for(int i=0;i<cnt;i++)
    82     {
    83         ans = max(ans,dfs(i));
    84     }
    85 
    86     printf("%d
    ",ans);
    87     return 0;
    88 }
  • 相关阅读:
    android中正确保存view的状态
    使用AudioTrack播放PCM音频数据(android)
    【录音】Android录音--AudioRecord、MediaRecorder
    (原创)初识cordova(一)
    忽略git中不需要进行版本管理的文件
    GitHub 小试
    通过View.post()获取View的宽高
    org.json.JSONObject的getString和optString使用注意事项
    android---EditText的多行输入框
    【转】我赌5毛你没见过这样的SpannableString
  • 原文地址:https://www.cnblogs.com/zzyDS/p/5650530.html
Copyright © 2011-2022 走看看