Color Length - UVa 1625 dp

来源:互联网 发布:手机降调软件 编辑:程序博客网 时间:2024/05/18 01:28

    题目只有PDF格式,就不复制了,不过话说这道题真的很好看(因为有颜色的小车很可爱吧)。

    题意:给你两个序列,分别只有大写字母,你需要把他们按照顺序变成一列,使得这列每种字母的最前面的和最后面的距离差  的和最小。

    思路:dp[i][j][0]表示整合第一列的前i个字符和第二列的前j个字符,且最后一个字符是第一列的的最小权值,同理dp[i][j][1]表示最后一个字符使第二列的的最小权值。每次增加一个字符的时候,遍历出它前面和后面是不是有同样颜色的车,如果有的话,权值+1。

    AC代码如下:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;char s1[5010],s2[5010];int dp[5010][5010][2],num1[5010][26],num2[5010][26],sum[26],INF=1000000000;int main(){ int t,i,j,k,n,m,p;  scanf("%d",&t);  while(t--)  { scanf("%s%s",s1+1,s2+1);    n=strlen(s1+1);    m=strlen(s2+1);    for(i=1;i<=n;i++)    { for(j=0;j<=25;j++)       num1[i][j]=num1[i-1][j];      num1[i][s1[i]-'A']++;    }    for(i=1;i<=m;i++)    { for(j=0;j<=25;j++)       num2[i][j]=num2[i-1][j];      num2[i][s2[i]-'A']++;    }    for(i=0;i<=25;i++)     sum[i]=num1[n][i]+num2[m][i];    dp[0][0][0]=0;    dp[0][0][1]=0;    for(i=1;i<=n;i++)    { dp[i][0][0]=dp[i-1][0][0];      dp[i][0][1]=INF;      for(k=0;k<=25;k++)      { p=num1[i-1][k];        if(p>0 && sum[k]-p>0)         dp[i][0][0]++;      }    }    for(i=1;i<=m;i++)    { dp[0][i][1]=dp[0][i-1][1];      dp[0][i][0]=INF;      for(k=0;k<=25;k++)      { p=num2[i-1][k];        if(p>0 && sum[k]-p>0)         dp[0][i][1]++;      }    }    for(i=1;i<=n;i++)    { for(j=1;j<=m;j++)      { dp[i][j][0]=min(dp[i-1][j][0],dp[i-1][j][1]);        dp[i][j][1]=min(dp[i][j-1][0],dp[i][j-1][1]);        for(k=0;k<=25;k++)        { p=num1[i-1][k]+num2[j][k];          if(p>0 && sum[k]-p>0)           dp[i][j][0]++;          p=num1[i][k]+num2[j-1][k];          if(p>0 && sum[k]-p>0)           dp[i][j][1]++;        }      }    }    printf("%d\n",min(dp[n][m][0],dp[n][m][1]));  }}


0 0
原创粉丝点击