• 4595. 【NOIP2016模拟7.8】String


    Description&Data Constraint

    有两种字符串 (S,T)。长度分别为 (n,m)。现在需要在 (S) 里面有序地选出 (k) 个子串,且在 (T) 中出现的顺序与这 (k) 个子串的顺序相同。问这k个子串最大的长度和。

    (n,mle10^3,kle10)

    Solution

    比较经典的 (dp)​。

    考虑 (f_{i,j,k}) 表示 (S) 到了第 (i) 位,(T) 到了第 (j) 位,已经选择了 (k) 个子串的最大长度和。

    但是由于当前位能否匹配与上一位有关,因此再开一维 (0/1) 表示 (i-1)(j-1) 是否匹配。

    转移:

    如果 (S_i=T_j),说明当前位可以匹配,那么 (f_{i,j,k,1}=max(f_{i-1,j-1,k,1},f_{i-1,j-1,k-1,0})+1)

    然后 (f_{i,j,k,0}=max{f_{i-1,j-1,k,0/1},f_{i,j-1,k,0/1},f_{i-1,j,k,0/1}})

    因为可以有空串,所以 (ans=max{f_{n,m,1 exttt{->}k,0/1}})

    Code

    #include<cstdio>
    #include<algorithm>
    #define N 1005
    #define K 11
    using namespace std;
    int n,m,kk,x,ans,f[N][N][K][3];
    char ch,a[N],b[N];
    int main()
    {
    	scanf("%d%d%d",&n,&m,&kk);
    	ch=getchar();
    	while (ch<'a'||ch>'z') ch=getchar();
    	x=0;
    	while (ch>='a'&&ch<='z') a[++x]=ch,ch=getchar();
    	while (ch<'a'||ch>'z') ch=getchar();
    	x=0;
    	while (ch>='a'&&ch<='z') b[++x]=ch,ch=getchar();
    	for (int i=1;i<=n;++i)
    		for (int j=1;j<=m;++j)
    			for (int k=1;k<=kk;++k)
    			{
    				if (a[i]==b[j]) f[i][j][k][1]=max(f[i-1][j-1][k-1][0],f[i-1][j-1][k][1])+1;
    				f[i][j][k][0]=max(max(max(f[i-1][j-1][k][0],f[i-1][j-1][k][0]),max(f[i][j-1][k][0],f[i][j-1][k][1])),max(f[i-1][j][k][0],f[i-1][j][k][1]));
    			}
    	for (int i=1;i<=kk;++i)
    		ans=max(max(f[n][m][i][1],f[n][m][i][0]),ans);
    	printf("%d
    ",ans);
    	return 0;
    } 
    
  • 相关阅读:
    python之isinstance和issubclass
    python中类的继承
    python中面向对象
    python中常用的内置模块
    Python常用模块
    python中的常用内置模块
    python中的包、模块及导入
    python中的内置函数(二)
    国内7大核心期刊
    PS学习列表
  • 原文地址:https://www.cnblogs.com/Livingston/p/15226659.html
Copyright © 2020-2023  润新知