zoukankan      html  css  js  c++  java
  • uva 10739【基础(区间)dp】

    Uva 10739

    题意:给定字符串,可以增加、删除、修改任意字符,问最少经过多少次操作使字符串回文。

    题解:定义dp[l][r]表示把从l到r的子串Sl...Sr变成回文串需要操作的最少次数。字符可以增删改,有的博客说增删是一样的,有的说增比删开销大,我倾向于后者,但前者是对的。因为显然s[l]==s[r]时,dp[l][r]=dp[l+1][r-1];当两者不相等时,可以删去s[l]或者s[r],状态转移到dp[l+1][r]+1或dp[l][r-1]+1,但是增加怎么加?一样的,在状态dp[l][r-1]的左边添加's[l-1]'=s[r],或在状态dp[l+1][r]的右边添加's[r+1]'=s[l],画图看看,这和删除确实一样;自然,也可以把s[l],s[r]修改成相同的,状态转移到dp[l+1][r-1]+1。

    直接循环里dp:

      

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 int dp[1050][1050];
     8 char s[1050];
     9 
    10 int Min(int a,int b,int c)
    11 {
    12     int t=min(a,b);
    13     return min(t,c);
    14 }
    15 
    16 int main()
    17 {
    18     int T;
    19     cin>>T;
    20     for(int cas=1;cas<=T;cas++)
    21     {
    22         cin>>s;
    23         int len=strlen(s);
    24         for(int i=0;i<len;i++) dp[i][i]=0;
    25         for(int i=len-1;i>=0;i--){
    26             for(int j=i+1;j<len;j++){
    27                 if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1];
    28                 else dp[i][j]=Min(dp[i+1][j],dp[i][j-1],dp[i+1][j-1])+1;
    29             }
    30         }
    31         cout<<"Case "<<cas<<": "<<dp[0][len-1]<<endl;
    32     }
    33     return 0;
    34 }

    或者记忆化搜索(dfs):

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 int dp[1050][1050];
     8 char s[1050];
     9 
    10 int dfs(int l,int r)
    11 {
    12     if(dp[l][r]!=-1) return dp[l][r];
    13     if(l>=r) return dp[l][r]=0;
    14     if(s[l]==s[r])
    15         dp[l][r]=dfs(l+1,r-1);
    16     else
    17         dp[l][r]=min(dfs(l+1,r-1),min(dfs(l+1,r),dfs(l,r-1)))+1;
    18     return dp[l][r];
    19 }
    20 
    21 int main()
    22 {
    23     int T;
    24     cin>>T;
    25     for(int cas=1;cas<=T;cas++)
    26     {
    27         cin>>s;
    28         int len=strlen(s);
    29         memset(dp,-1,sizeof(dp));
    30         cout<<"Case "<<cas<<": "<<dfs(0,len-1)<<endl;
    31     }
    32     return 0;
    33 }
  • 相关阅读:
    Go Revel
    Go Revel
    Go Revel
    Go Revel
    deployment:声明式的升级应用
    Kubernetes架构及相关服务详解
    Docker 安装MySQL
    日志收集-Elk6
    Jenkins-Multijob plugin多任务串并行
    ansible创建vmware虚拟机
  • 原文地址:https://www.cnblogs.com/zxhyxiao/p/8469321.html
Copyright © 2011-2022 走看看