String painter HDU - 2476 区间dp+思维

题意:给定a,b两个字符串,让你求将a刷成b所要的最少的次数,刷的时候只能刷连续的一个区间。

思路:先计算出由空串刷成b串的最少次数,因为有相同字符的存在,所以才能尽可能地少刷,设d[i][j]为区间i到j的最少次数,如果第i位和第j位上的字符相同,那么就等价于区间i+1到j的最少话费,因为是由空串转移必然可以先刷i到j,再刷i+1到j-1之间串,如果对应位不相同,那么枚举k,i<k<j,有可能有第k位与第i位相同,然后分成两部分,分别计算更新最小值。

最后,再递推计算一下答案,设ans[i]为a串前i项刷成b串前i项需要的最少次数,如果a[i]==b[i],ans[i]=ans[i-1],依然枚举一下区间去更新,ans[i]=min(ans[i],ans[k]+d[k+1][i])

#include <iostream>  
#include <cstdio>  
#include <assert.h>  
#include <cstring>  
#include <algorithm>  
#include <vector>  
#include <map>  
#include <cmath>  
#include <set>  
#include <queue>  
using namespace std;  
  
const int INF=1e9+10;  
const double EPS = 1e-10;    
typedef long long ll;  
const ll mod=998244353;

char a[105],b[105];
int d[105][105],ans[105];

int main(){
    //freopen("out.txt","w",stdout);
	while(scanf("%s%s",a+1,b+1)!=EOF){
		int len=strlen(b+1);
		for(int i=len;i>=1;i--){
			for(int j=i;j<=len;j++){
				if(i==j) d[i][j]=1;
				else{
					if(b[i]==b[j]){
						d[i][j]=d[i+1][j];
					}else{
						d[i][j]=d[i+1][j]+1;
						for(int k=i;k<j;k++)
							d[i][j]=min(d[i][j],d[i][k]+d[k+1][j]);
					}
				}
			}
		}
		ans[0]=0;
		for(int j=1;j<=len;j++){
			if(a[j]==b[j])
				ans[j]=ans[j-1];
			else 
				ans[j]=ans[j-1]+1;
			for(int i=0;i<j;i++)
				ans[j]=min(ans[j],ans[i]+d[i+1][j]);
		}
		printf("%d\n",ans[len] );
	}	
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值