String painter HDU - 2476

原题链接

考察:区间dp

 这道题可以想到P4170涂色和Acwing 编辑距离的结合.

错误思路:

      如果直接按a[i]==b[i]与a[j]==b[j]划分的话(实际上a[i]==b[i]与j可以合并),就会少了考虑b连续的条件.使得次数增加了.

错误思路2:

     将a[i]==a[j]&&b[i]==b[j]与b[i]==a[i]合并起来考虑,这样思路是对的但是划分集合真的太太太太繁琐了.

正确思路:

     实际上是将上面分两步进行.当a[j]==b[j]时,f[i][j] = f[i][j-1].但是当a[j]!=b[j],我们只能通过b的[i,j]区间是否有连续(即b[i]与b[j]的关系)来减少步数.

          f[i][j] = min(f[i][k]+f[k+1][j],f[i][j]).

     这里可以采取预处理的方式,也就是像P4170那道题一样先求出空白串->B,在考虑a[i]与b[i]的关系进行进一步的消减.当a[i]==b[i],那么i不用涂了,当a[i]!=b[i]要更新f[1][i]使得前面的更新连续到i处.

注意:f[1][i]不能改成f[1][i] = f[1][i-1]+f[i][i],因为优化点不一定在i-1点

如:  axcxx  aycyy

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 using namespace std;
 6 const int N = 110;
 7 char a[N],b[N];
 8 int f[N][N];
 9 int main()
10 {
11     while(scanf("%s%s",a+1,b+1)!=EOF)
12     {
13         int n = strlen(a+1); memset(f,0,sizeof f);
14         for(int i=1;i<=n;i++)  f[i][i] = 1;
15         for(int len=2;len<=n;len++)
16            for(int l=1;l+len-1<=n;l++)
17            {
18                  int r = l+len-1;
19                  f[l][r] = 0x3f3f3f3f;
20                  if(b[l]==b[r]) f[l][r] = min(f[l+1][r],f[l][r-1]);
21                  else 
22                     for(int k=l;k<r;k++)
23                       f[l][r] = min(f[l][r],f[l][k]+f[k+1][r]);
24            }
25         for(int i=1;i<=n;i++)
26         {
27             if(a[i]==b[i]) 
28                f[1][i] = f[1][i-1];
29             else 
30                for(int l=1;l<i;l++)
31                  f[1][i] = min(f[1][l]+f[l+1][i],f[1][i]);
32         }
33         printf("%d\n",f[1][n]);
34     }
35     return 0;
36 }

 

posted @ 2021-02-12 05:01  acmloser  阅读(57)  评论(0编辑  收藏  举报