HDU 2476 String painter(区间dp)

这道题就不怎么想得到了

题意:给一个A串B串,每次只能将一段连续区间内的字母改成另外的同一个字母,问A变成B的最少操作次数。

做法:先假设AB都不想等,g[i][j]表示i~j这个区间最少的操作.

首先最基础的递推g[i][j]=g[i+1][j]+1;表示需要在上一个递推的区间上,操作一次。

然后枚举短点,if(b[i]==b[k]) g[i][j]=min(g[i][j],g[i+1][k]+g[k+1][j]);

表示i和k的位置相同,在变换A串的时候,可以在操作k的位置的时候,顺便把i的位置也操作了,注意这里是B串的i和k位置。

这样我们得到了,AB都不同的情况的答案。

然后用一个ans数组记录答案,不断更新答案,具体操作看代码。

#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int g[N][N],n,ans[N];
int main()
{
    char a[110],b[110];
    while(~scanf("%s",a+1))
    {
        scanf("%s",b+1);
        n=strlen(a+1);
        memset(g,0,sizeof(g));
        for(int i=1;i<=n;i++)
        {
            g[i][i]=1;
        }
        for(int l=2;l<=n;l++)
        {
            for(int i=1;i<=n-l+1;i++)
            {
                int j=i+l-1;
                g[i][j]=g[i+1][j]+1;
                for(int k=i+1;k<=j;k++)
                {
                    if(b[i]==b[k])
                    {
                        g[i][j]=min(g[i][j],g[i+1][k]+g[k+1][j]);
                    }
                }
            }
        }
        memset(ans,0,sizeof(ans));
        for(int i=1;i<=n;i++)
            ans[i]=g[1][i];
        for(int i=1;i<=n;i++)
        {
            if(a[i]==b[i])
                ans[i]=ans[i-1];
            else
                for(int j=1;j<i;j++)
                    ans[i]=min(ans[i],ans[j]+g[j+1][i]);
        }
        printf("%d\n",ans[n]);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值