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): 2068    Accepted Submission(s): 908


    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
     
    Source
     
    Recommend
    lcy
    题目描述 : 给定一个初始串,目标串,每步可以通过改变一个连续的子串使其变为同一个字母,至少需要多少步?
    我们发现一段序列,每一步的选择是可以改变任意长度的连续子串,
    那么通过枚举改变哪些连续子串,可以包含所有的情况。
    d[i]表示以i结尾的序列变成目标串需要的最少步骤。d[i]=min(d[i],d[k]+dp[k+1][i]),因为是[k+1,i]区间是连续改变的,
    那么我们可以将dp[k+1][i]看成是表示[k+1,i]区间内一个相同串到目标串的最少步骤(刷[k+1,i]区间内的字符串,使这段连续的子串变为同一个字母).
    初始化dp[i][i]=1;
    dp[i][j]=dp[i][j-1]+1;
    if(a[i]==a[k])   //有相同的连续改变才会有作用,不同,无论通过何种方式.每一个都需要改变,改变次数都一样
    //相同的话,通过连续改变,可以减少改变次数,
    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j-1]);
    初始化d数组为0,d[i]=dp[0][1];
    d[i]=min(d[i],d[k]+dp[k+1][i-1]);
    通过枚举改变的连续子串的长度
    动态规划: 定义状态,每一步的选择,包含了所有的可能性
    最优子结构无后效性,如果状态设计不合理,会导致有后效性。
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    char a[105],b[105];
    int dp[105][105],d[105];
    int Length;
    void init()
    {
        memset(dp,0,sizeof(dp));
        memset(d,0,sizeof(d));
        for(int i=0;i<Length;i++)
            dp[i][i]=1;
    
    }
    void solve()
    {
           /*   for(int i=0;i<Length;i++)
                for(int j=0;j<Length;j++)
                 for(int k=i;k<=j;k++)
               {
                 dp[i][j]=min(DP(dp[i][k]+dp[k+1][j]),dp[i][j]);
               }
               for(int s=0;s<Length;s++)
               {
                for(int j=0;j<Length;j++)
                 printf("%d ",dp[s][j]);
                   printf("
    ");
               }
                printf("2
    ");
            printf("%d
    ",dp[0][Length-1]);
          */
           for(int t=1;t<Length;t++)
            for(int i=0;i<Length;i++)
          {
              int j=i+t;
              if(j>=Length)
                break;
              dp[i][j]=dp[i][j-1]+1;
              for(int k=i;k<j;k++)
              {
                  if(b[k]==b[j])   //如果目标串有相同的,就可以一同处理
                  dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j-1]);
              }
          }
    
            for(int i=0;i<Length;i++)
                d[i]=dp[0][i];
            for(int i=0;i<Length;i++)
            {
                if(a[i]==b[i])
                    d[i]=d[i-1];
                else
                {
                    for(int k=0;k<i;k++)
                     d[i]=min(d[i],d[k]+dp[k+1][i]);
                }
    
            }
    }
    int main()
    {
        //freopen("test.txt","r",stdin);
        while(~scanf("%s%s",a,b))
        {
            Length=strlen(a);
             init();
             solve();
             printf("%d
    ",d[Length-1]);
        }
        return 0;
    }
     
  • 相关阅读:
    Struts2 Hello World
    Struts2入门(1)
    Struts2_day01
    Java Web Model2实战
    Oracle_day04
    SAP调用外部webservice接口
    通用清账程序
    服务器IDOC文件解析程序
    IDOC接口创建步骤
    SAP 本地发送IDOC
  • 原文地址:https://www.cnblogs.com/xianbin7/p/4482912.html
Copyright © 2011-2022 走看看