• BZOJ2423 [HAOI2010]最长公共子序列


    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

    本文作者:ljh2000
    作者博客:http://www.cnblogs.com/ljh2000-jump/
    转载请注明出处,侵权必究,保留最终解释权!

    题目链接:BZOJ2423

    正解:DP

    解题报告:

      考虑用f[i][j]表示第一个字符序列的前i位与第二个字符序列的前j位的最长公共子序列长度,那么转移的就直接根据这一位是否对应相等转即可:

      f[i][j]=f[i-1][j-1]+1(a[i]=b[j]);f[i][j]=max(f[i][j-1],f[i-1][j])(a[i]!=b[j])。

      第二问有一点麻烦…

      要讨论一下每个取值在哪取到,不能算重了…

      考虑一下f[i][j]和之前的哪些相同,yy一下就可以咯。

    //It is made by ljh2000
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <map>
    #include <set>
    #include <string>
    #include <complex>
    using namespace std;
    typedef long long LL;
    typedef long double LB;
    typedef complex<double> C;
    const double pi = acos(-1);
    const int MAXN = 5011;
    const int mod = 100000000;
    char ch[MAXN],s[MAXN];
    int n,m,f[2][MAXN],g[2][MAXN];
    
    inline int getint(){
        int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
        if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
    }
    
    inline void work(){
    	scanf("%s",ch+1); scanf("%s",s+1);
    	n=strlen(ch+1); m=strlen(s+1); n--; m--;
    	for(int i=0;i<=m;i++) g[0][i]=1;//边界!
    	int tag=0; g[1][0]=1;
    	for(int i=1;i<=n;i++) {
    		tag^=1; 
    		//memset(f[tag],0,sizeof(f[tag]));
    		//memset(g[tag],0,sizeof(g[tag]));
    		for(int j=1;j<=m;j++) {
    			if(ch[i]==s[j]) {
    				f[tag][j]=f[tag^1][j-1]+1;
    				g[tag][j]=g[tag^1][j-1];
    				g[tag][j]+=(f[tag][j]==f[tag^1][j])*g[tag^1][j];
    				g[tag][j]+=(f[tag][j]==f[tag][j-1])*g[tag][j-1];
    			}
    			else {
    				f[tag][j]=max(f[tag][j-1],f[tag^1][j]);
    				g[tag][j]=(f[tag][j]==f[tag^1][j])*g[tag^1][j];
    				g[tag][j]+=(f[tag][j]==f[tag][j-1])*g[tag][j-1];
    				g[tag][j]-=(f[tag][j]==f[tag^1][j-1])*g[tag^1][j-1];
    			}
    			g[tag][j]%=mod;
    		}
    	}
    	printf("%d
    ",f[tag][m]);
    
    	g[tag][m]+=mod; g[tag][m]%=mod;
    	printf("%d",g[tag][m]);
    }
    
    int main()
    {
        work();
        return 0;
    }
    

      

  • 相关阅读:
    weak_ptr解决shared_ptr环状引用所引起的内存泄漏[转]
    如何限制对象只能建立在堆上或者栈上(转载)
    为了异常安全(swap,share_ptr)——Effecive C++
    注意类型转换——Effective C++
    http协议
    【java.math.BigInteger】常用函数
    【java.math.BigInteger】【转】常见问题
    【思路,dp,BigInteger】ZOJ
    【Warshall_Floyd】
    【Dijkstra】
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6506745.html
Copyright © 2020-2023  润新知