UVA 1625 Color Length (DP)

题意:见紫书P276

思路:(设一个颜色序列为s1,另一个为s2)要把最优子结构找到是关键,状态就是天然的执行步骤,d(i,j)表示s1移走了i个元素

s2移走了j个元素的状态。下一步只有两个决策,决策后的剩余的问题和原问题一样,这就是最优子结构。所以每次决策时要保证决策的产生的花费+子问题的解达到最优

所以状态方程显然:dp[i][j]=min(dp[i+1][j],dp[i][j+1])+res[i][j]

本题的难点在于求res[i][j],所以要在之前对字符串做预处理

代码:

//0 KB 22 ms
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 5050
#define inf 0x3f3f3f3f
char s1[N],s2[N];
int col1[26][2],col2[26][2];
int dp[N][N];

void ini(){
    memset(col1,-1,sizeof(col1));
    memset(col2,-1,sizeof(col2));
}
inline int add(int x,int y){
    int s=0;
    for(int i=0;i<26;i++){
        if(col1[i][1]<=x&&col2[i][1]<=y) continue;
        if((col1[i][0]>x&&col2[i][0]>y)||(col1[i][0]>x&&col2[i][0]==-1)||(col2[i][0]>y&&col1[i][0]==-1)) continue;
        s++;

    }
    return s;
}             
int main(){

    int T;
    scanf("%d",&T);
    while(T--){
        ini();
        scanf("%s%s",s1,s2);
        int len1=strlen(s1);
        int len2=strlen(s2);
        for(int i=0;i<len1;i++){
            if(col1[s1[i]-'A'][0]<0){
                col1[s1[i]-'A'][0]=i;
                col1[s1[i]-'A' ][1]=i;
            }
            else col1[s1[i]-'A' ][1]=i;
        }
        for(int i=0;i<len2;i++){
            if(col2[s2[i]-'A'][0]<0){
                col2[s2[i]-'A' ][0]=i;
                col2[s2[i]-'A'][1]=i;
            }

            else col2[s2[i]-'A' ][1]=i;
        }
        dp[len1&1][len2]=0;
        for(int i=len1;i>=0;i--)
        for(int j=len2;j>=0;j--){
            if(i==len1&&j==len2) continue;
            int t1=inf,t2=inf;
            int tmp=add(i-1,j-1);
            if(i<=len1-1) t1=dp[(i+1)&1][j]+tmp;
            if(j<=len2-1) t2=dp[i&1][j+1]+tmp;
            dp[i&1][j]= min(t1,t2);
        }

        printf("%d\n",dp[0&1][0]);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值