• poj1699


    题目:给你一些序列,要求进行合并合并完最短。eg,AGCT与CTAA 可以合并成AGCTAA(CT相同)

    思路:先进行预处理,处理出i串与j串合并完的程度。。

           然后进行dp或者记忆化搜索

           因为n很小,所以我们可以进行状态压缩

           用一个  <2^10的数来表示该字符串连接了没,所以

      f[i][j]表示此时状态为J,最后一个放的是第I个的最短长度

          f[i][j] = f[k][j + (1 <<k - 1)]+s[k] - len[i][k]           ( i放过且k没放过,len[i][k],表示k接在相同字母数 )

     1 、*
     2    State:Accepted
     3    Time:2013-03-18 18:35:21
     4 */
     5 #include<iostream>
     6 #include<cstring>
     7 #include<cstdlib>
     8 #include<string>
     9 #include<cstdio>
    10 #include<cmath>
    11 #include<algorithm>
    12 #define M 1 << 12
    13 #define CLR(NAME) memset(NAME , 0 ,sizeof(NAME))
    14 using namespace std;
    15 const int Inf = 1010101;
    16 char s[15][250];
    17 int n, f[M][12], T , len[15][15], MX ,ln[150];
    18 
    19 void init(){
    20      scanf("%d",&n);
    21      MX = 1 << n;
    22      for (int i = 1; i <= n; ++i){
    23        scanf("%s",&s[i]);
    24        ln[i] = strlen(s[i]);
    25      }
    26 }
    27 
    28 int  work_out(int a, int b){
    29      int la , lb , LL;
    30      la = strlen(s[a]);
    31      lb = strlen(s[b]);
    32      for (int i = 0; i < la; ++i )
    33        {
    34           LL = 0;
    35           for (int j = 0; j < lb; ++j)
    36             {
    37               if (i + j >=  la) break;
    38               if (s[a][i + j] == s[b][j]) ++LL;
    39             }
    40           if  (LL == la - i) return LL;
    41        }
    42      return 0;
    43 }
    44 
    45 void solve(){
    46      CLR(f);
    47      CLR(len);
    48      int opt;
    49      for (int i = 1; i <= n; ++i)
    50          for (int j = 1; j <= n; ++j)
    51             if (i != j)
    52             len[i][j] = work_out(i , j);
    53      for (int i = 0; i < MX; ++i)
    54          for (int j = 0; j <= n; ++j)
    55              f[i][j] = Inf;
    56      for (int i = 1; i <= n ; ++i)
    57            f[1 << (i - 1)][i] = ln[i];
    58 
    59      for (int i = 0; i < MX; ++i)
    60          for (int j = 1; j <= n; ++j)
    61             if (1 << (j - 1) & i)
    62               {
    63                  if (f[i][j] == Inf) continue;
    64                  for (int k = 1; k <= n; ++k)
    65                    {
    66                       if ((i & (1 << (k - 1))) != 0){
    67                     //         printf("%d & 1<<%d = %d\n", i , k -1, i & 1 << (k - 1));
    68                              continue;
    69                       }
    70                       opt = i | (1 << (k-1));
    71                       f[opt][k] = min(f[opt][k],f[i][j] + ln[k] - len[j][k]);
    72                    }
    73 
    74               }
    75    /*  for (int i = 0; i < MX; ++i)
    76          for (int j = 1; j <= n; ++j)
    77             if (1 << (j - 1) & i  && f[i][j] != Inf)
    78               printf("f[%d][%d] = %d\n",i , j ,f[i][j]);*/
    79      int ans = Inf;
    80      for (int i = 1; i <= n; ++i)
    81        ans = min(ans, f[MX - 1][i]);
    82      printf("%d\n",ans);
    83 }
    84 int main(){
    85      scanf("%d",&T);
    86      while (T--){
    87           init();
    88           solve();
    89      }
    90 }
  • 相关阅读:
    6. (在第五步的基础上展开)实现模板推送发送
    5. (全局唯一接口调用凭据)获取Access token
    3. openid的获取
    2. 验证服务器地址的有效性
    Java后端开发规范
    4. (自定义菜单和删除全部菜单)Springboot读取静态json文件
    Docker私有仓库搭建与部署
    Docker容器基础学习一
    运维日志切割--logrotate
    zookeeper学习
  • 原文地址:https://www.cnblogs.com/yzcstc/p/2977861.html
Copyright © 2020-2023  润新知