• 杭电1503_输出最长公共子序列


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1503

    题目大意:给你两个字符串, 让你合并两个字符串,每个字符串里的字符相对位置不改变,字符可以共用, 输出最短的目标字符串

    思路:先求出最长公共子序列的长度, 再倒序,求出一条最长子字符串,每个字符记录各在s1 和 s2 的位置,然后输出。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cstdlib>
     6 #include <cmath>
     7 #include <set>
     8 #include <map>
     9 #include <vector>
    10 using namespace std;
    11 
    12 int max(int a, int b)
    13 {
    14     return a > b ? a : b;
    15 }
    16 struct node
    17 {
    18     int a1, a2;
    19 }a[110];//记录s1 和 s2 第 i 个相同字母分别在s1(a1) 和 s2(a2) 的位置
    20 int main()
    21 {    
    22     char s1[110], s2[110], s[210]; //s为目标字符串
    23     int dp[110][110], i, j;//dp 用来最长公共子序列
    24     while(~scanf("%s %s", s1 + 1, s2 + 1))
    25     {
    26         strcpy(s, "");
    27         int l1 = strlen(s1 + 1), l2 = strlen(s2 + 1);
    28         memset(dp, 0, sizeof(dp));
    29         for(i = 1; i <= l1; i++)
    30         {
    31             for(j = 1; j <= l2; j++)
    32             {
    33                 dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);
    34                 if(s2[j] == s1[i])
    35                     dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);//求最长公共子序列
    36             }
    37         }
    38         int k = 0, mm = dp[l1][l2], ii = l1 + 1, jj = l2 + 1;
    39         for(i = l1; i > 0; i--)//倒序
    40         {
    41             for(j = l2; j > 0; j--)
    42             {     
    43                 if(i < ii && j < jj){//注意, WA 了一发
    44                     if(s1[i] == s2[j]) { //s1 和 s2 前一个相同的字母i, j 应该分别在此位置i, j 的前面     
    45                         if(dp[i][j] == dp[i - 1][j - 1] + 1 && dp[i][j] == mm)
    46                         {
    47                             k++;
    48                             a[k].a1 = i, a[k].a2 = j;
    49                             mm--;
    50                             ii = i, jj = j;
    51                         }
    52                     }
    53                 }                
    54                 if(mm == 0)
    55                     break;
    56             }
    57         }
    58         i = 1, j = 1;
    59         int t = -1;
    60         while(k > 0)
    61         {
    62             while(i < a[k].a1)
    63             {
    64                 s[++t] = s1[i];
    65                 i++;
    66                 
    67             }
    68             while(j < a[k].a2)
    69             {
    70                 s[++t] = s2[j];
    71                 j++;
    72             }
    73             s[++t] = s1[i];
    74             i++, j++;
    75             k--;
    76         }
    77         while(i <= l1){
    78             s[++t] = s1[i];
    79             i++;            
    80         }
    81         while(j <= l2){
    82             s[++t] = s2[j];
    83             j++;
    84         }
    85         s[++t] = '';
    86         cout << s << endl;
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    线程池
    自定义死锁
    不安全线程取钱
    JUC Lock实现类ReentrantLock使用说明
    同步方法跟同步方法块 synchronized
    线程的管程法跟信号灯法_生产者消费模式
    CopyOnWriteArrayList JUC当中安全容器
    inserttextatcursorinacontenteditablediv
    Android开发——NDK开发入门
    Linux下线程同步对象(1)——互斥量
  • 原文地址:https://www.cnblogs.com/luomi/p/5513496.html
Copyright © 2020-2023  润新知