Color Length - UVa 1625 dp

本文介绍了一道关于两序列字母的排列组合问题,并通过动态规划算法求解最小权值的方法。具体实现中,使用了二维数组记录中间状态,最终得出最优解。

    题目只有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]));
  }
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值