Spoj, dynamic-programming: AIBOHP - Aibohphobia

August 12, 2016
spoj

给一个字符串,求最少插入多少个字符,可以使得这个字符串是回文的。

可以这样想:我们假设它已经是回文的,那么把这个字符串逆序,如果它是回文的,那么对 应的每个字符应该相等。可以它不是回文的,那么就需要尽量少地加一些字符,加多少呢? 那么需要知道当前的最长连续公共子序列的长度len,把不相等的那些字符串加进去就成为 了回文的。加进去的字符的最少个数 = 字符串长度 - 原先的字符串和它的逆序字符串的最 长连续公共子序列的长度。

问题就转化为求两个序列的最长公共子序列。这个就简单了。

因为懒并且想省时间,所以就用了一些宏,这让程序变得不易读,还好程序比较简单,不太 影响吧。反正以后也不会再读。。了解思路就可以了。

/*
 * =====================================================================================
 *
 *       Filename:  main.cpp
 *
 *    Description:  http://www.spoj.com/problems/AIBOHP/
 *
 *        Version:  1.0
 *        Created:  08/12/2016 18:27:30
 *       Compiler:  g++
 *
 *         Author:  Sabastian (liuxueyang.github.io), liuxueyang457@gmail.com
 *
 * =====================================================================================
 */
#include <bits/stdc++.h>
using namespace std;
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define rep(i, a, n) for (int i = a; i < n; ++i)
#define per(i, a, n) for (int i = n-1; i > a; --i)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef map<int,int> MI;
typedef long long ll;
typedef pair<int,int> PII;
const ll MOD=1000000007;
const int N=6120;
int a[N][N];
char s[N],t[N],str[N];
  int
main ( void )
{
#ifndef  ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
#endif     /* -----  ONLINE_JUDGE  ----- */

  int T;cin>>T;while(T--){
    memset(a,0,sizeof(a));
    cin>>str;int len=strlen(str);
    rep(i,0,len)s[i+1]=str[i];
    rep(i,1,len+1)t[len+1-i]=s[i];
    rep(i,1,len+1){
      rep(j,1,len+1){
        if(s[i]==t[j]){
          a[i][j]=max(a[i][j],a[i-1][j-1]+1);
        }
        else {
          int mm=max(a[i-1][j],a[i][j-1]);
          a[i][j]=max(a[i][j],mm);
        }
      }
    }
    cout<<len-a[len][len]<<endl;
  }

  return EXIT_SUCCESS;
}				/* ----------  end of function main  ---------- */
comments powered by Disqus