HDOJ 2476 - String painter 不是所有的区间DP都方便用记忆化搜索..

            题意:

                     给了两个长度相同的串(长度不超过100..且仅含小写字母)..现在需要让第一个串变成第二个串...可以做的操作是将一片连续的区域变成相同的字母..问最少的操作步数..

            题解:

                     很明显的区间DP..不过..我用dfs记忆化搜索写跪了...

                     参考别人的代码..才搞出来..感觉这无法写记忆化搜索..因为更新时不能保证所有区域都更新到...

                     主要的思想...找前面相同的一起更新过来..也就是同前面哪个位置一起染色...而且做完DP后还要来统计答案..也是同样的思想..


Program:

#include<iostream>      
#include<algorithm>      
#include<stdio.h>      
#include<string.h>    
#include<time.h>   
#include<map>   
#include<math.h>      
#include<queue>      
#define MAXN 105
#define MAXM 500005 
#define oo 1000000007      
#define ll long long      
#define MOD 1000000  
using namespace std;   
int dp[MAXN][MAXN],ans[MAXN];
char A[MAXN],B[MAXN];
void DP(int n)
{
      int i,j,l,r,L;
      memset(dp,0,sizeof(dp));
      for (i=1;i<=n;i++) dp[i][i]=1;
      for (L=1;L<n;L++)
         for (l=1;l<=n && l+L<=n;l++)
         {  
               r=l+L;
               dp[l][r]=dp[l+1][r]+1; 
               for (i=l+1;i<=r;i++)
                  if (B[l]==B[i]) //跟哪个一起染色 
                    dp[l][r]=min(dp[l][r],dp[l+1][i]+dp[i+1][r]); 
         }
      return;
}
int main()     
{     
      int len,i,j; 
      while (gets(A+1) && gets(B+1))
      {
               len=strlen(A+1);
               memset(dp,-1,sizeof(dp));
               DP(len); 
               for (i=1;i<=len;i++)
               {
                       ans[i]=dp[1][i];
                       if (A[i]==B[i]) ans[i]=ans[i-1];
                          else 
                             for (j=1;j<i;j++) // 找前面能一起过来的
                                ans[i]=min(ans[i],ans[j]+dp[j+1][i]);
               }
               printf("%d\n",ans[len]);
      }
      return 0;    
}    


你可能感兴趣的:(HDOJ 2476 - String painter 不是所有的区间DP都方便用记忆化搜索..)