紫书动规 例题9-8 UVA - 1625 Color Length dp

题目链接:

https://vjudge.net/problem/UVA-1625

题意:

题解:

蒟蒻感觉非常难
dp[i][]j] := 第一个串拿i个,第二个串拿j个的最小值
维护一个w[i][j] blablabla 看紫书吧
http://www.cnblogs.com/candy99/p/5985217.html

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MS(a) memset(a,0,sizeof(a))
#define MP make_pair
#define PB push_back
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
inline ll read(){
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
//////////////////////////////////////////////////////////////////////////
const int maxn = 5e3+10;

int n,m;
char a[maxn],b[maxn];
int bg[maxn][2],ed[maxn][2],w[maxn][maxn];
int dp[maxn][maxn],f[maxn][maxn];

int main(){
    int T = read();
    while(T--){
        scanf("%s%s",a+1,b+1);
        n=strlen(a+1),m=strlen(b+1);
        for(int i=0; i<=26; i++) bg[i][0]=bg[i][1] = INF;
        for(int i=0; i<=26; i++) ed[i][0]=ed[i][1] = 0;
        for(int i=1; i<=n; i++){
            int c = a[i]-'A';
            if(bg[c][0] == INF) bg[c][0] = i;
            ed[c][0] = i; 
        }
        for(int i=1; i<=m; i++){
            int c = b[i]-'A';
            if(bg[c][1] == INF) bg[c][1] = i;
            ed[c][1] = i;
        }

        for(int i=0; i<=n; i++){
            for(int j=0; j<=m; j++){
                if(!i && !j) continue;

                int t1 = INF, t2 = INF;
                if(i>0) t1 = dp[i-1][j]+w[i-1][j];
                if(j>0) t2 = dp[i][j-1]+w[i][j-1];
                dp[i][j] = min(t1,t2);

                if(i > 0){
                    w[i][j] = w[i-1][j];
                    int c = a[i] - 'A';
                    if(bg[c][0]==i && bg[c][1]>j) w[i][j]++;
                    if(ed[c][0]==i && ed[c][1]<=j) w[i][j]--;
                }else{
                    w[i][j] = w[i][j-1];
                    int c = b[j] - 'A';
                    if(bg[c][1]==j && bg[c][0]>i) w[i][j]++;
                    if(ed[c][1]==j && ed[c][0]<=i) w[i][j]--;
                }
            }
        }

        cout << dp[n][m] << endl;

    }

    return 0;
}

// http://www.cnblogs.com/candy99/p/5985217.html
posted @ 2017-03-15 22:57  _yxg123  阅读(229)  评论(0编辑  收藏  举报