zoukankan      html  css  js  c++  java
  • HDU 2476:String painter 区间DP好题

    String painter

    题目链接:

    http://poj.org/problem?id=2476

    题意:

    给出两个相同长度的字符串(仅由小写字母组成)s1,s2,每次操作可以将s1的任意一段区间改变成一个相同的字母,求将s1改变成s2所需的最少操作次数。

    题解:

    设dp[i][j]是将s1的区间[i,j]部分改成s2相同部分的最少操作次数,终点状态为dp[1][t]( t 为长度)。

    先求出一个和s2没有任何相同部分的字符串转化为s2所需的最少次数,再求s1转化为s2的最少次数即可。

                  

    代码

    #include<stdio.h>
    #include<string.h>
    const int N=101;
    int dp[N][N];
    char s1[N],s2[N];
    int mmin(int x,int y)
    {
      return x<y?x:y;
    }
    void solve()
    {
      int n,m,x;
      memset(dp,0,sizeof(dp));
      while(~scanf("%s%s",s1+1,s2+1))
      {
        s1[0]=s2[0]='?';
        int t=strlen(s1)-1;
        for(int len=0;len<t;++len)
        for(int i=1;i+len<=t;++i)
        {
          int j=len+i;
          dp[i][j]=dp[i][j-1]+1;
          for(int k=i;k<j;++k)
          {
            if(s2[k]==s2[j])dp[i][j]=mmin(dp[i][j],dp[k+1][j-1]+dp[i][k]);//考虑到s2串为aaaaaaa的情况这里必须是+dp[i][k],而不能是+dp[i][k-1]+1,刷[i,k]的时候顺便刷到 j 就好了
            dp[i][j]=mmin(dp[i][j],dp[i][k-1]+dp[k][j]);
          }
        }
        for(int len=0;len<t;++len)
        for(int i=1;i+len<=t;++i)
        {
          int j=len+i;
          if(s1[j]==s2[j]&&s1[i]==s2[i])
          {
            dp[i][j]=mmin(dp[i][j],dp[i+1][j-1]);
          }
          else
          {
            for(int k=i;k<=j;++k)
              if(dp[i][k]+dp[k+1][j]<dp[i][j])
                dp[i][j]=dp[i][k]+dp[k+1][j];
          }
        }
        printf("%d ",dp[1][t]);
      }
    }
    int main()
    {
      solve();
      return 0;
    }

     
  • 相关阅读:
    HBA登录验证
    html转pdf
    html转pdf
    html转word
    python生成html
    python生成pdf
    Word另存为不同的格式
    WORD转HTML-python第三方包Mammoth(官方文档翻译)
    深入浅谈,CPU设计原理
    CPU,寄存器,缓存,RAM,ROM的作用和他们之间的联系
  • 原文地址:https://www.cnblogs.com/kiuhghcsc/p/5751989.html
Copyright © 2011-2022 走看看