2 条题解

  • 0
    @ 2025-10-8 16:57:05
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    inline int read(){
        int sum=0,f=1;char ch=getchar();
        while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
        return f*sum;
    }
    
    int f[101][101],tot=0;
    char a[101],b[101];
    int f1[27][101],f2[27][101];
    string ans[999];
    
    void find(int l1,int l2,string s,int l){
        if(l1<0||l2<0) return ;
        if(l<=0){ans[++tot]=s;return ;}
        for(int i=1;i<=26;i++){
            int p1=f1[i][l1],p2=f2[i][l2];
            if(f[p1][p2]!=l) continue;
            char c=i+96;
            find(p1-1,p2-1,c+s,l-1);
        }
    }
    
    int main(){
    
        cin>>a>>b;tot=0;
        memset(f,0,sizeof(f));
        memset(f1,0,sizeof(f1));memset(f2,0,sizeof(f2));
        int la=strlen(a),lb=strlen(b);
        for(int i=la;i;i--) a[i]=a[i-1];
        for(int i=lb;i;i--) b[i]=b[i-1];//这两步是整体位移,个人习惯而已
        for(int i=1;i<=26;i++){
            for(int j=1;j<=la;j++){
                if(a[j]==i+96) f1[i][j]=j;
                else f1[i][j]=f1[i][j-1];
            }
            for(int j=1;j<=lb;j++){
                if(b[j]==i+96) f2[i][j]=j;
                else f2[i][j]=f2[i][j-1];
            }
        }//记录f1,f2
        for(int i=1;i<=la;i++){
            for(int j=lb;j>=1;j--){
                f[i][j]=max(f[i-1][j],f[i][j+1]);
                if(a[i]==b[j]) f[i][j]=max(f[i-1][j+1]+1,f[i][j]);
            }
        }//寻找最长公共子序列
        find(la,lb,"",f[la][lb]);
        sort(ans+1,ans+tot+1);
        for(int i=1;i<=tot;i++) cout<<ans[i]<<endl;
    
        return 0;
    }
    
    • 0
      @ 2025-10-8 16:56:39
      #include <iostream>
      #include <cstdio>
      #include <cstring>
      #include <string>
      #include <algorithm>
      using namespace std;
      
      inline int read(){
          int sum=0,f=1;char ch=getchar();
          while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
          while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
          return f*sum;
      }
      
      int f[101][101],tot=0;
      char a[101],b[101];
      int f1[27][101],f2[27][101];
      string ans[1001];
      
      void find(int l1,int l2,string s,int l){
          if(l1<0||l2<0) return ;
          if(l<=0){ans[++tot]=s;return ;}
          for(int i=1;i<=26;i++){
              int p1=f1[i][l1],p2=f2[i][l2];
              if(f[p1][p2]!=l) continue;
              char c=i+96;
              find(p1-1,p2-1,c+s,l-1);
          }
      }
      
      int main(){
      
          cin>>a>>b;tot=0;
          memset(f,0,sizeof(f));
          memset(f1,0,sizeof(f1));memset(f2,0,sizeof(f2));
          int la=strlen(a),lb=strlen(b);
          for(int i=la;i;i--) a[i]=a[i-1];
          for(int i=lb;i;i--) b[i]=b[i-1];//这两步是整体位移,个人习惯而已
          for(int i=1;i<=26;i++){
              for(int j=1;j<=la;j++){
                  if(a[j]==i+96) f1[i][j]=j;
                  else f1[i][j]=f1[i][j-1];
              }
              for(int j=1;j<=lb;j++){
                  if(b[j]==i+96) f2[i][j]=j;
                  else f2[i][j]=f2[i][j-1];
              }
          }//记录f1,f2
          for(int i=1;i<=la;i++){
              for(int j=1;j<=lb;j++){
                  f[i][j]=max(f[i-1][j],f[i][j-1]);
                  if(a[i]==b[j]) f[i][j]=max(f[i-1][j-1]+1,f[i][j]);
              }
          }//寻找最长公共子序列
          find(la,lb,"",f[la][lb]);
          sort(ans+1,ans+tot+1);
          for(int i=1;i<=tot;i++) cout<<ans[i]<<endl;
      
          return 0;
      }
      
      
      • 1

      0x50 动态规划(练习)4:[SPOJ33]Trip

      信息

      ID
      1402
      时间
      1000ms
      内存
      64MiB
      难度
      5
      标签
      递交数
      59
      已通过
      24
      上传者