String painter HDU

来源:互联网 发布:什么时候开放网络购彩 编辑:程序博客网 时间:2024/06/05 01:06

题意:给定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;}


原创粉丝点击