UVa1625 Color Length

来源:互联网 发布:宁波淘宝托管 编辑:程序博客网 时间:2024/04/27 14:47

题目描述
传送门


参照刘汝佳书上的思路。一开始自己写了个记忆化搜索超时了,哪位高人能指点一下超时的原因…

//TLE!#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;int l1,l2,b1[200],b2[200],e1[200],e2[200],d[5010][5010],cnt=0;//d[i][j]表示s1,s2分别取了i,j个颜色,还需要的L值char s1[20010],s2[20010];int dp(int i,int j,int tot){//tot表示已经出现但未结束的颜色的总数    if(i>l1||j>l2) return 100000000;    if(d[i][j]>-1) return d[i][j];    d[i][j]=tot;    int t1=tot,t2=tot;    if(i+1==b1[s1[i+1]]&&(b2[s1[i+1]]>j||b2[s1[i+1]]==-1)) t1++;    if(i+1==e1[s1[i+1]]&&(e2[s1[i+1]]<=j||b2[s1[i+1]]==-1)) t1--;    if(j+1==b2[s2[j+1]]&&(b1[s2[j+1]]>i||b1[s2[j+1]]==-1)) t2++;    if(j+1==e2[s2[j+1]]&&(e1[s2[j+1]]<=i||b1[s2[j+1]]==-1)) t2--;//计算其他的tot    return d[i][j]+=min(dp(i+1,j,t1),dp(i,j+1,t2));//转移}int main(){    int t;    cin>>t;    while(t--){        memset(b1,-1,sizeof(b1));        memset(b2,-1,sizeof(b2));        scanf("%s%s",s1+1,s2+1);        l1=strlen(s1+1),l2=strlen(s2+1);        for(int i=1;i<=l1;i++){//计算s1里每种颜色的开始和结束位置(b1表示开始的位置,e1表示结束的位置,下同)            if(b1[s1[i]]==-1) b1[s1[i]]=i;            e1[s1[i]]=i;        }        for(int i=1;i<=l2;i++){//计算s2里每种颜色的开始和结束位置            if(b2[s2[i]]==-1) b2[s2[i]]=i;            e2[s2[i]]=i;        }        memset(d,-1,sizeof(d));        d[l1][l2]=0;        printf("%d\n",dp(0,0,0));    }    return 0;}

后来换成递推的就AC了

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;int l1,l2,b1[200],b2[200],e1[200],e2[200],d[5010][5010],tot[5010][5010];char s1[20010],s2[20010];int main(){    int t;    cin>>t;    while(t--){        memset(b1,-1,sizeof(b1));        memset(b2,-1,sizeof(b2));        scanf("%s%s",s1+1,s2+1);        l1=strlen(s1+1),l2=strlen(s2+1);        for(int i=1;i<=l1;i++){            if(b1[s1[i]]==-1) b1[s1[i]]=i;            e1[s1[i]]=i;        }        for(int i=1;i<=l2;i++){            if(b2[s2[i]]==-1) b2[s2[i]]=i;            e2[s2[i]]=i;        }        for(int i=0;i<=l2+1;i++) d[l1+1][i]=1000000000;        for(int i=0;i<=l1+1;i++) d[i][l2+1]=1000000000;        d[l1][l2]=0;        tot[0][0]=0;        for(int i=0;i<=l1;i++){            for(int j=0;j<=l2;j++){                int t1=tot[i][j],t2=tot[i][j];                if(i+1==b1[s1[i+1]]&&(b2[s1[i+1]]>j||b2[s1[i+1]]==-1)) t1++;                if(i+1==e1[s1[i+1]]&&(e2[s1[i+1]]<=j||b2[s1[i+1]]==-1)) t1--;                if(j+1==b2[s2[j+1]]&&(b1[s2[j+1]]>i||b1[s2[j+1]]==-1)) t2++;                if(j+1==e2[s2[j+1]]&&(e1[s2[j+1]]<=i||b1[s2[j+1]]==-1)) t2--;                tot[i+1][j]=t1;tot[i][j+1]=t2;            }        }        for(int i=l1;i>=0;i--){            for(int j=l2;j>=0;j--){                if(i==l1&&j==l2) continue;                d[i][j]=min(d[i+1][j],d[i][j+1])+tot[i][j];            }        }        printf("%d\n",d[0][0]);    }    return 0;}               
原创粉丝点击