动态规划

带通配符的字符串匹配

http://noi.openjudge.cn/ch0206/6252/

#include <bits/stdc++.h>
using namespace std;
int main(){
    bool dp[30][30]={0};
    dp[0][0]=1;
    string x,y,t=" "; 
    cin>>x>>y;
    x=t+x,y=t+y;
    for(int i=1;i<x.size();i++){
        if(x[i]=='*')
            dp[i][0]=1;
        else
            break;
    }
    for(int i=1;i<x.size();i++){
        for(int j=1;j<y.size();j++){
            if(x[i]==y[j]||x[i]=='?'){
                dp[i][j]=dp[i-1][j-1];
            }
            else if(x[i]=='*'){
                if(dp[i-1][j-1]||dp[i-1][j]||dp[i][j-1])
                    dp[i][j]=true;
                else
                    dp[i][j]=false;
            }
            else if(x[i]!=y[j]){
                dp[i][j]=false;
            }
        }
    }
    if(dp[x.size()-1][y.size()-1])
        cout<<"matched";
    else
        cout<<"not matched";
} 
View Code

计算字符串距离

http://noi.openjudge.cn/ch0206/2988/

#include <iostream>
#include <cmath>
#include <memory.h>
using namespace std;
int dp[1010][1010];
int fmin(int x,int y,int z){
    return min(x,min(y,z));
}
int main(){
    int T;
    cin>>T;
    while(T--){
        memset(dp,0,sizeof(dp));
        string x,y;
        cin>>x>>y;
        for(int i=0;i<=x.size();i++){
            dp[i][0]=i;
        }
        for(int i=0;i<=y.size();i++){
            dp[0][i]=i;
        }
        for(int i=0;i<x.size();i++){
            for(int j=0;j<y.size();j++){
                if(x[i]==y[j]) dp[i+1][j+1]=dp[i][j];
                else dp[i+1][j+1]=fmin(dp[i][j+1],dp[i+1][j],dp[i][j])+1;
            }
        }
        cout<<dp[x.size()][y.size()]<<endl;

    }
}
View Code

切割回文

http://noi.openjudge.cn/ch0206/8471/

#include <iostream>
#include <cmath>
#include <memory.h>
using namespace std;
int dp[1010];
string x;
bool f(int l,int r){
    for(int i=l;i<=(l+r)/2;i++){
        if(x[i]!=x[l+r-i])
            return 0;
    }
    return 1;
}
int main(){
    int T;
    cin>>T;
    while(T--){
        int ans=1e9;
        memset(dp,0x3f,sizeof(dp));
        cin>>x;
        for(int i=0;i<x.size();i++){
            if(f(0,i)) dp[i]=0;
            else{
                for(int j=i;j>=0;j--){
                    if(f(j,i))
                        dp[i]=min(dp[i],dp[j-1]+1);
                }
            }
        }
        cout<<dp[x.size()-1]<<endl;
    }
}
View Code

 补充:

11/19

程序考试,两道原题计算字符串距离、切割回文,

切割回文没打出来,非常失落,

没和一维数组联系起来,满脑子递归,

上次打出来这个题其实也是先打了递归代码,理解了之后再转dp,

dp和递归区别,在这里就是数组记录了每一次结果,后续不用计算调用之前计算好了的结果,

爬楼梯这个例子可以好好理解一下。

考试还有一个失败地方,看见做过的题净想着回忆上次怎么做的,

然后回忆不起来,裂开。其实就当成新题做就挺好,相信自己。

哦,递归方法超时了,贴一下代码,很好理解。

 1 #include <iostream>
 2 #include <cmath>
 3 #include <memory.h>
 4 using namespace std;
 5 string x;
 6 bool f(int l,int r){
 7     for(int i=l;i<=(l+r)/2;i++){
 8         if(x[i]!=x[l+r-i])
 9             return 0;
10     }
11     return 1;
12 }
13 int hh(int l,int r,int ans){
14     if(f(l,r))
15         return ans;
16     else{
17         int mn=1e9;
18         for(int i=r;i>=l+1;i--){
19             if(f(i,r))
20                 mn=min(mn,hh(l,i-1,ans+1));
21         }
22         ans=mn;
23     }
24     return ans;
25 }
26 int main(){
27     int T;
28     cin>>T;
29     while(T--){
30         cin>>x;
31         cout<<hh(0,x.size()-1,0)<<endl;
32     }
33 }
View Code

打完力扣最长回文子串后,我觉得切割回文我打了一个假的dp,二维矩阵记录是否是回文状态都没有,我再想想。

明白了,关于判断是否是回文,应该用状态矩阵记录,不然的话,要再写一个for循环判断。。。。我失败了(noi的数据太水了!!!)

力扣最长回文子串就超时了一上午。。。。

应该是先两个for得出所有回文子串情况保存在二维数组里,然后f函数那里改成查询二维矩阵相应数值是否为1,这样f这里O(n)时间变成O(1)时间

奇怪,可能noi数据有问题,之前14s现在21s,时间上确实优化了一个for循环,上代码。

 1 #include <iostream>
 2 #include <cmath>
 3 #include <memory.h>
 4 using namespace std;
 5 int dp[1010];
 6 bool f[1010][1010]; 
 7 string s;
 8 void ff(int n){
 9     for(int i=0;i<n;i++){//长度为1和2的直接初始化 
10         f[i][i]=1;
11         if(s[i]==s[i+1])
12             f[i][i+1]=1;
13     }
14     for(int len=3;len<=n;len++){
15         
16         for(int i=0;i+len-1<n;i++){
17             int j=i+len-1;//右边界 
18             if(s[i]==s[j]&&f[i+1][j-1]){
19                 f[i][j]=1;
20             }else{
21                 f[i][j]=0;
22             }
23         }
24     }
25 }
26 int main(){
27     int T;
28     cin>>T;
29     while(T--){
30         int ans=1e9;
31         memset(dp,0x3f,sizeof(dp));
32         cin>>s;
33         ff(s.size());
34         for(int i=0;i<s.size();i++){
35             if(f[0][i]) dp[i]=0;
36             else{
37                 for(int j=i;j>=0;j--){
38                     if(f[j][i])
39                         dp[i]=min(dp[i],dp[j-1]+1);
40                 }
41             }
42         }
43         cout<<dp[s.size()-1]<<endl;
44     }
45 }
View Code
原文地址:https://www.cnblogs.com/hcl6/p/13933881.html