UVA 1625 Color Length 颜色的长度 (预处理+dp)

dp[i][j]表示前一个序列拿了i个颜色,后一个序列拿了j个颜色的最小花费。

转移的时候显然只能向dp[i+1][j],或dp[i][j+1]转移,每增加拿走一个颜色,之前已经出现但没结束的颜色个数的跨度都增加1,为了在转移的时候快速算出这个值,先预处理出每个颜色在各个序列中的起始和终止位置。

memset (dp),然后就GG了

#include<bits/stdc++.h>
using namespace std;

#define FOR(i,s,e) for(int i = s; i < e; i++)
#define RFOR(i,e,s) for(int i = e-1; i >= s; i--)
#define bug(x) cout<<#x<<'='<<endl

#define MP make_pair
#define PB push_back
#define fi first
#define se second

#define CLR(x) memset(x,0,sizeof(x));
#define CLRTo(x,v) memset(x,v,sizeof(x));

const int maxn = 5001;

int dp[maxn][maxn];

const int N = 26;
char s1[maxn];
char s2[maxn];
bool vis[N];
int ed2[N],ed1[N];
int st1[N],st2[N];

#define GetEd(x)
CLR(vis);
for(i = n##x-1; i >= 0; i--){
    int id = s##x[i] - 'A';
    if(!vis[id]){
        vis[id] = true;
        ed##x[id] = i;
    }
}

#define GetSt(x)
CLR(vis);
for(i = 0; s##x[i]; i++){
    int id = s##x[i] - 'A';
    if(!vis[id]){
        vis[id] = true;
        st##x[id] = i;
    }
}
n##x = i;

int cal(int i,int j)
{
    int ret = 0;
    for(int k = 0; k < N; k++){
        bool f1 = j>=st2[k] || i>=st1[k];
        bool f2 = j<ed2[k] || i < ed1[k];
        ret += f1&&f2;
    }
    return ret;
}

const int INF = 0x3fffffff;

int main()
{
    //freopen("in.txt","r",stdin);
    int T; scanf("%d",&T);
    while(T--){
        scanf("%s%s",s1,s2);
        int i;
        int n1 ,n2 ;
        fill(st1,st1+N,INF);
        fill(st2,st2+N,INF);
        fill(ed1,ed1+N,-INF);
        fill(ed2,ed2+N,-INF);
        GetSt(1) GetSt(2)
        GetEd(1) GetEd(2)
        for(i = 0; i <= n1; i++){
            for(int j = 0; j <= n2; j++){
                if(i&&j){
                    dp[i][j] = min(dp[i-1][j],dp[i][j-1])+cal(i-1,j-1);
                }else {
                    if(i){
                        dp[i][j] = dp[i-1][j]+cal(i-1,j-1);
                    }else if(j){
                        dp[i][j] = dp[i][j-1]+cal(i-1,j-1);
                    }else {
                        dp[i][j] = 0;
                    }
                }
            }
        }
        printf("%d
",dp[n1][n2]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jerryRey/p/4740944.html