hdu 4681 string

  2013 Multi-University Training Contest 8

这是我第一次做多校联合的题目,虽然当时一道也没有做出来,但谁不是这样起步的呢?

1 利用贪心的思想, 先枚举a, b字符串中包含c的最短区间, 然后两次for循环求区间两端的最长公共子序列长度,     取最大值加上c的长度就是答案了

2 求最长公共子序列之前可进行预处理,这样每次处理时只要调用即可,不然可能会超时

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char a[1010], b[1010], c[1010];
int dp1[1010][1010], dp2[1010][1010];
typedef struct
{
  int s;
  int e;
}
ans;
ans ansa[1010], ansb[1010];
int la, lb, lc;
void DP()
{
 int i, j;
 char c;
 for(i=0; i<=la; i++)
   dp1[i][0] = 0;
 for(i=1; i<=lb; i++)
   dp1[0][i] = 0;
 for(i=1; i<=la; i++)
   for(j=1; j<=lb; j++)
     {
       if(a[i] == b[j])
         dp1[i][j] = dp1[i-1][j-1] + 1;
       else 
         dp1[i][j] = max(dp1[i-1][j], dp1[i][j-1]);
     }
 for(i=1, j=la; i < j; i++, j--)
   {
    c = a[i];
    a[i] = a[j];
    a[j] = c;
   }
 for(i=1, j=lb; i<j; i++, j--) 
   {
    c = b[i];
    b[i] = b[j];
    b[j] = c;
   } 
 for(i=0; i<=la; i++)
   dp2[i][0] = 0;
 for(i=1; i<=lb; i++)
   dp2[0][i] = 0;
 for(i=1; i<=la; i++)
   for(j=1; j<=lb; j++)
    {
      if(a[i] == b[j])
        dp2[i][j] = dp2[i-1][j-1] + 1;
      else 
        dp2[i][j] = max(dp2[i-1][j], dp2[i][j-1]);
    }
  return;
}
int main()
{
  int t, ca;
  ca = 1;
  scanf("%d", &t);
  getchar();
  while(t--)
   {
    int i, j, k, t1, t2, m;
    gets(a + 1);
    gets(b + 1);
    gets(c + 1);
    la = strlen(a + 1);
    lb = strlen(b + 1);
    lc = strlen(c + 1);
    t1 = t2  = 1;
    for(i=1; i<=la; i++)
      {
        if(a[i] == c[1])
          {
            k = 2;
            for(j=i+1; j<=la && k<=lc; j++)
              if(c[k] == a[j])
                k++;
            if(k-1 == lc)
             {
              ansa[t1].s = i;
              ansa[t1++].e = j - 1;      
             }
          }     
      }
    for(i=1; i<=lb; i++)
      {
        if(b[i] == c[1])
          {
            k = 2;
            for(j=i+1; j<=lb && k<=lc; j++)
              if(b[j] == c[k])
               k++;
            if(k-1 == lc)
             {
                ansb[t2].s = i;
                ansb[t2++].e = j - 1;
             }
            
          }
      }
    DP();
    m = 0;
    for(i=1; i<t1; i++)
      for(j=1; j<t2; j++)
         m = max(m, dp1[ansa[i].s][ansb[j].s] + dp2[la + 1 - ansa[i].e][lb + 1 - ansb[j].e]);
    printf("Case #%d: %d\n", ca++, m + lc - 2);
   }
 return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值