首页 > 代码库 > Color Length UVALive - 5841

Color Length UVALive - 5841

题文:见网页:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3852,(紫书p276)

 

题解:

这个题目统计答案,或者说状态的转移十分巧妙,我们想如果设dp[i][j]表示一号串到了第i位,二号串到了第j位的最小话费,显然还要记一下最开始放入这个字母的位置,十分不好写对不对,并且也状压不下。

那么我们可以考虑,对于一个状态dp[i][j],我们不最后来算他是多少,我们可以一边加,一边判断,看前面有那些字母已经出现了,并且后面还有这个字母,那么显然对于每个这种字母,都要有1的花费,所以,这个题目就变成了如何维护当前满足上述定义的字母的个数,这个我们主要分类讨论一下就可以了,具体实现看代码吧。

 

代码:(其实可以不用滚动数组)

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<stdlib.h>
#define ll long long
const int MAXN=5010;
const int inf=1<<30;
using namespace std;
int dp[2][MAXN],c[2][MAXN];
int op1[27],ed1[27],op2[27],ed2[27];
int n,m;
char x[MAXN],y[MAXN];
int main(){
    int t;scanf("%d",&t);
    while(t--){
        memset(dp,0,sizeof(dp));
        memset(c,0,sizeof(c));
        scanf("%s%s",x+1,y+1);
        int n=strlen(x+1),m=strlen(y+1);
        for(int i=1;i<=n;i++) x[i]-=A;
        for(int i=1;i<=m;i++) y[i]-=A;
        memset(op1,127,sizeof(op1));
        memset(op2,127,sizeof(op2));
        memset(ed1,0,sizeof(ed1));
        memset(ed2,0,sizeof(ed2));
        for(int i=1;i<=n;i++){
            op1[x[i]]=min(op1[x[i]],i);
            ed1[x[i]]=i;
        }
        for(int i=1;i<=m;i++){
            op2[y[i]]=min(op2[y[i]],i);
            ed2[y[i]]=i;
        }
        int now=0,last=1;dp[0][0]=0;
        for(int i=0;i<=n;i++){
            now^=1,last^=1;
            memset(dp[now],0,sizeof(now));
            memset(c[now],0,sizeof(now));
            for(int j=0;j<=m;j++){
                if(!i&&!j) continue;
                int v1=inf,v2=inf;
                if(j) v1=dp[now][j-1]+c[now][j-1];
                if(i) v2=dp[last][j]+c[last][j];
                dp[now][j]=min(v1,v2);
                if(i){
                    c[now][j]=c[last][j];
                    if(op1[x[i]]==i&&op2[x[i]]>j) c[now][j]++;
                    if(ed1[x[i]]==i&&ed2[x[i]]<=j) c[now][j]--;
                }
                else if(j){
                    c[now][j]=c[now][j-1];
                    if(op2[y[j]]==j&&op1[y[j]]>i) c[now][j]++;
                    if(ed2[y[j]]==j&&ed1[y[j]]<=i) c[now][j]--;
                }
            }
        }
        printf("%d\n",dp[now][m]);
    }
}

 

Color Length UVALive - 5841