zoukankan      html  css  js  c++  java
  • HDU_2476_String painter_(区间dp)

    String painter

    Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3935    Accepted Submission(s): 1833


    Problem Description
    There are two strings A and B with equal length. Both strings are made up of lower case letters. Now you have a powerful string painter. With the help of the painter, you can change a segment of characters of a string to any other character you want. That is, after using the painter, the segment is made up of only one kind of character. Now your task is to change A to B using string painter. What’s the minimum number of operations?
     
    Input
    Input contains multiple cases. Each case consists of two lines:
    The first line contains string A.
    The second line contains string B.
    The length of both strings will not be greater than 100.
     
    Output
    A single line contains one integer representing the answer.
     
    Sample Input
    zzzzzfzzzzz
    abcdefedcba
    abababababab
    cdcdcdcdcdcd
     
    Sample Output
    6
    7
     
    2017.3.18复习,感觉这道题的dp设计很巧妙,还是没有吃透。。。

     
    题意:给定两个等长字符串A、B,一次操作可以将A的任意一段连续的字符变为同一任意字符,问最少多少次操作可以将A变为B。
     
    专门挑的区间dp的题,但是然并卵。。。没思路啊。。。看题解。。。
     
    思路:dp[i][j]:将空串变为B[i-->j]所需要的最少次数。先求出所有dp[i][j],即求出将空串变为B[i-->j]所需最少次数。那么根据dp数组求出最终答案就很容易:
    1.ans[k]=dp[1][k]
     
    2.if(A[k]==B[k])   ans[k]=ans[k-1];     (ans[0]==0)
     else  ans[k]=min(ans[k],ans[t]+ans[t+1][k]);  (1=<t<k)
     
    求dp[i][j]:
    枚举起点i、终点j、遍历[i+1,j]区间k

    for(int j=1;j<=len;j++) //end
    {
      for(int i=j;i>0;i--) //begin
      {
        dp[i][j]=dp[i+1][j]+1;
        for(int k=i+1;k<=j;k++)
          if(B[i]==B[k])
            dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]);
       }
    }

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    char A[105],B[105];
    int dp[105][105];
    int ans[105];
    
    int main()
    {
        while(scanf("%s%s",A+1,B+1)!=EOF)
        {
            memset(dp,0,sizeof(dp));
            memset(ans,0,sizeof(ans));
            int len=strlen(B+1);
            for(int j=1;j<=len;j++)  //end
            {
                for(int i=j;i>0;i--)  //begin
                {
                    dp[i][j]=dp[i+1][j]+1;
                    for(int k=i+1;k<=j;k++)  //一定是从左往右找重的
                        if(B[i]==B[k])
                            dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]);
                }
            }
            for(int i=1;i<=len;i++)
            {
                ans[i]=dp[1][i];
                if(A[i]==B[i])
                    ans[i]=ans[i-1];
                else
                {
                    for(int j=1;j<i;j++)
                        ans[i]=min(ans[i],ans[j]+dp[j+1][i]);
                }
            }
            printf("%d
    ",ans[len]);
        }
        return 0;
    }

     

     

  • 相关阅读:
    DXF文件格式理解
    Qt Creator调试命令行参数
    qt编译错误:invalid new-expression of abstract class type "*"
    dxf文件解析库libdxf初探
    ubuntu linux编译libdxfrw
    CAD DWG/DXF文件C++解析库libdxfrw
    AutoCAD版本dxf文件与dxflib解析库支持探索
    Linux 6种日志查看方法(转)
    码率、分辨率、帧率和画质计算单位时间码流大小(转)
    纯手工打造车载车牌识别检测系统(转)
  • 原文地址:https://www.cnblogs.com/jasonlixuetao/p/6503388.html
Copyright © 2011-2022 走看看