题意:给出两个串a和b,一次只能将一个区间刷一次,问最少几次能让a=b
思路:首先考虑最坏的情况,就是先将一个空白字符串刷成b需要的次数,直接区间DP[i][j]表示i到j的最小次数。
再考虑把a变成b的次数 ans[i]:a从(0,i)变成b(0,i)所需的最小次数
初始化ans[i]=dp[0][i]
如果a[i]==b[i],则ans[i]=ans[i-1];
由小区间更新到大区间
1 //#pragma comment(linker, "/STACK:167772160")//手动扩栈~~~~hdu 用c++交 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <iostream> 6 #include <queue> 7 #include <stack> 8 #include <cmath> 9 #include <set> 10 #include <algorithm> 11 #include <vector> 12 #include <map> 13 // #include<malloc.h> 14 using namespace std; 15 #define clc(a,b) memset(a,b,sizeof(a)) 16 #define LL long long 17 const int inf = 0x3f3f3f3f; 18 const double eps = 1e-5; 19 // const double pi = acos(-1); 20 const LL MOD = 9901; 21 const int N = 110; 22 23 // inline int r(){ 24 // int x=0,f=1;char ch=getchar(); 25 // while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘) f=-1;ch=getchar();} 26 // while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 27 // return x*f; 28 // } 29 char a[N],b[N]; 30 int dp[N][N]; 31 int ans[N]; 32 33 int main(){ 34 while(~scanf("%s%s",a,b)){ 35 int n=strlen(a); 36 clc(dp,0); 37 for(int i=0;i<n;i++){ 38 for(int j=i;j<n;j++){ 39 dp[i][j]=j-i+1; 40 } 41 } 42 43 for(int len=0;len<n;len++){ 44 for(int i=0;i<n&&i+len<n;i++){ 45 int j=i+len; 46 dp[i][j]=dp[i+1][j]+1; 47 for(int k=i+1;k<=j;k++){ 48 if(b[i]==b[k]) 49 dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]); 50 } 51 } 52 } 53 54 if(a[0]==b[0]) { 55 ans[0]=0; 56 } 57 else 58 ans[0]=1; 59 for(int i=1;i<n;i++){ 60 ans[i]=dp[0][i]; 61 if(a[i]==b[i]){ 62 ans[i]=ans[i-1]; 63 } 64 else{ 65 for(int k=0;k<i;k++){ 66 ans[i]=min(ans[i],ans[k]+dp[k+1][i]); 67 } 68 } 69 } 70 printf("%d\n",ans[n-1]); 71 } 72 return 0; 73 }
时间: 2024-12-28 01:44:31