UVA 1625 Color Length

来源:互联网 发布:布光模拟软件 编辑:程序博客网 时间:2024/05/01 02:02

Problem Description

这里写图片描述

输入两个颜色序列,要求按顺序合并成一个序列,即每次把一个序列的开头的颜色放到新序列的尾部。对于每个颜色c来说,其跨度l(c),表示c的最大位置和最小位置的差。

你的任务是找一种合并方式使得所有l(c)的总和最小。dp[i][j]表示第一个串移走了i个元素,第二个串移走了j个元素还需要多少费用。

dp[i][j]表示的是,当序列1取了i个,序列2取了j个时,对“已经出现,但还没有结束的颜色”的影响

普通的状态转移比较麻烦,要考虑每个颜色上一次出现的位置。我们换一种思路,不是等到一个颜色转移之后再计算,而是每一次累加,当把一个颜色移到最终序列前,把所有已经出现但是没有结束的颜色的l(c)加一。进一步,不需要关注每个颜色的l(c),只需要知道多少种颜色已经开始但是没有结束。

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<stack>#include<set>#include<map>#include<queue>#include<algorithm>using namespace std;char a[5005],b[5005];int dp[5005][5005];int starta[26],enda[26],startb[26],endb[26];int main(){    int kase;    scanf("%d",&kase);    int lena,lenb;    int i,j,k;    while(kase--){        scanf("%s",a);        scanf("%s",b);        lena=strlen(a);        lenb=strlen(b);        for(i=0;i<26;i++){            starta[i]=99999999;            startb[i]=99999999;            enda[i]=-99999999;            endb[i]=-99999999;        }        for(i=0;i<lena;i++){                a[i]-='A';            if(starta[a[i]]==99999999){                starta[a[i]]=i+1;            }            enda[a[i]]=i+1;        }        for(i=0;i<lenb;i++){                b[i]-='A';            if(startb[b[i]]==99999999){                startb[b[i]]=i+1;            }            endb[b[i]]=i+1;        }        for(i=0;i<=lena;i++){            for(j=0;j<=lenb;j++){                dp[i][j]=0;                for(k=0;k<26;k++){                    if((i>=starta[k]||j>=startb[k])&&(i<enda[k]||j<endb[k]))                        dp[i][j]++;                }                if(i==0&&j==0)                    continue;                else if(i==0)                    dp[i][j]+=dp[i][j-1];                else if(j==0)                    dp[i][j]+=dp[i-1][j];                else                    dp[i][j]+=min(dp[i-1][j],dp[i][j-1]);            }        }        printf("%d\n",dp[lena][lenb]);    }    return 0;}


0 0
原创粉丝点击