码迷,mamicode.com
首页 > 其他好文 > 详细

P2679 子串

时间:2018-10-26 19:35:05      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:deque   lse   org   pac   ios   href   using   进制   lin   

传送门

思路:

  设 f [ i ][ j ][ k ][ 0/1 ] 表示 A 串匹配到第 i 个,B 串匹配到第 j 个,已经匹配到第 k 段,0: A[ i ] 与 B[ j ] 不匹配, 1: A[ i ] 与 B[ j ] 匹配。

  状态转移可分为 A[ i ] 与 B[ j ] 匹配和不匹配两种状态:

  ① 若不匹配, f [ i ][ j ][ k ][ 0 ] = f [ i-1 ][ j ][ k ][ 0 ] + f [ i-1 ][ j ][ k ][ 1 ] 。

  ② 匹配,f [ i ][ j ][ k ][ 1 ] = f [ i-1 ][ j-1 ][ k-1 ][ 1 ] + f [ i-1 ][ j-1 ][ k-1 ][ 0 ] + f [ i-1 ][ j-1 ][ k ][ 1 ] 。

  如果直接将 f 数组开到 4 维,128M 的空间明显不够。

  考虑到每次的状态转移只和前一次的状态有关,所以可以将 f 的第一维用二进制滚动 。

Code:

70 Points:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<stack>
#include<vector>
#include<queue>
#include<deque>
#include<map>
#include<set>
using namespace std;
#define lck_max(a,b) ((a)>(b)?(a):(b))
#define lck_min(a,b) ((a)<(b)?(a):(b))
typedef long long LL;
const int maxn=101;
const int mod=1e9+7;
LL n,m,K,ans,f[(maxn<<1)+(maxn<<3)][maxn<<1][maxn<<1][2];
char s1[(maxn<<1)+(maxn<<3)],s2[maxn<<1];
inline LL read()
{
    LL kr=1,xs=0;
    char ls;
    ls=getchar();
    while(!isdigit(ls))
    {
        if(!(ls^45))
            kr=-1;
        ls=getchar();
    }
    while(isdigit(ls))
    {
        xs=(xs<<1)+(xs<<3)+(ls^48);
        ls=getchar();
    }
    return xs*kr;
}
inline void out(LL xs)
{
    if(!xs) {putchar(48); return;}
    if(xs<0) putchar(-),xs=-xs;
    int kr[57],ls=0;
    while(xs) kr[++ls]=xs%10,xs/=10;
    while(ls) putchar(kr[ls]+48),ls--;
}
int main()
{
    n=read();m=read();K=read();
    scanf("%s",s1+1);scanf("%s",s2+1);
    f[0][0][0][0]=1;
    for(LL i=1;i<=n;i++)
    {
        f[i][0][0][0]=1;
        for(LL j=1;j<=m;j++)
        {
            for(LL k=1;k<=K;k++)
            {
                f[i][j][k][0]=(f[i-1][j][k][0]+f[i-1][j][k][1])%mod;
                if(s1[i]==s2[j])
                    f[i][j][k][1]=(f[i-1][j-1][k][1]+f[i-1][j-1][k-1][0]+f[i-1][j-1][k-1][1])%mod;
            }
        }
    }
    out((f[n][m][K][0]+f[n][m][K][1])%mod);
return 0;
}

 

100 Points:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<stack>
#include<vector>
#include<queue>
#include<deque>
#include<map>
#include<set>
using namespace std;
#define lck_max(a,b) ((a)>(b)?(a):(b))
#define lck_min(a,b) ((a)<(b)?(a):(b))
typedef long long LL;
const int maxn=101;
const int mod=1e9+7;
bool pos=true;
LL n,m,K,ans,f[2][maxn<<1][maxn<<1][2];
char s1[(maxn<<1)+(maxn<<3)],s2[maxn<<1];
inline LL read()
{
    LL kr=1,xs=0;
    char ls;
    ls=getchar();
    while(!isdigit(ls))
    {
        if(!(ls^45))
            kr=-1;
        ls=getchar();
    }
    while(isdigit(ls))
    {
        xs=(xs<<1)+(xs<<3)+(ls^48);
        ls=getchar();
    }
    return xs*kr;
}
inline void out(LL xs)
{
    if(!xs) {putchar(48); return;}
    if(xs<0) putchar(-),xs=-xs;
    int kr[57],ls=0;
    while(xs) kr[++ls]=xs%10,xs/=10;
    while(ls) putchar(kr[ls]+48),ls--;
}
int main()
{
    n=read();m=read();K=read();
    scanf("%s",s1+1);scanf("%s",s2+1);
    f[0][0][0][0]=1;f[1][0][0][0]=1;
    for(LL i=1;i<=n;i++,pos^=1)
    {
        for(LL j=1;j<=m;j++)
        {
            for(LL k=1;k<=K;k++)
            {
                f[pos][j][k][0]=(f[pos^1][j][k][0]+f[pos^1][j][k][1])%mod;
                if(s1[i]==s2[j])
                    f[pos][j][k][1]=(f[pos^1][j-1][k][1]+f[pos^1][j-1][k-1][0]+f[pos^1][j-1][k-1][1])%mod;
                else f[pos][j][k][1]=0;
            }
        }
    }
    out((f[n&1][m][K][0]+f[n&1][m][K][1])%mod);
return 0;
}

 

P2679 子串

标签:deque   lse   org   pac   ios   href   using   进制   lin   

原文地址:https://www.cnblogs.com/lck-lck/p/9857652.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!