CodeForces 682D Alyona and Strings

$dp$,最长公共子序列变形。

$f[i][j][h][0]$表示:$s[1 \cdots i]$与$t[1 \cdots j]$,分成了$k$段,并且$s[i]$与$t[j]$之后没有切的最优解。

$f[i][j][h][1]$表示:$s[1 \cdots i]$与$t[1 \cdots j]$,分成了$k$段,并且$s[i]$与$t[j]$之后切了一段的最优解。

$f[i][j][h][0]$可以从$f[i-1][j][h][0]$,$f[i-1][j][h][1]$,$f[i][j-1][h][0]$,$f[i][j-1][h][1]$转移过来。

如果$s[i]=t[j]$,$f[i][j][h][1]$就可以从$f[i-1][j-1][h-1][0]$和$f[i-1][j-1][h-1][1]$转移过来。

如果$s[i]=t[j]$并且$s[i-1]=t[j-1]$,$f[i][j][h][1]$还可以从$f[i-1][j-1][h][1]$转移过来。

大致和最长公共子序列过程相似。时间复杂度$O(n*m*k)$。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-6;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c = getchar(); x = 0;
    while(!isdigit(c)) c = getchar();
    while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
}

const int maxn=1010;
char s[maxn],t[maxn];
int n,m,k,f[maxn][maxn][13][2];

int main()
{
    scanf("%d%d%d",&n,&m,&k);
    scanf("%s%s",s+1,t+1);
    s[0]='.'; t[0]=',';
    memset(f,-1,sizeof f);

    for(int i=0; i<=n; i++) for(int j=0; j<=m; j++)
        f[i][j][0][0]=f[i][j][0][1]=0;

    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            for(int h=1; h<=k; h++)
            {
                if(s[i]==t[j])
                {
                    if(s[i-1]==t[j-1]&&f[i-1][j-1][h][1]!=-1)
                        f[i][j][h][1]=max(f[i][j][h][1],f[i-1][j-1][h][1]+1);

                    if(f[i-1][j-1][h-1][0]!=-1)
                        f[i][j][h][1]=max(f[i][j][h][1],f[i-1][j-1][h-1][0]+1);

                    if(f[i-1][j-1][h-1][1]!=-1)
                        f[i][j][h][1]=max(f[i][j][h][1],f[i-1][j-1][h-1][1]+1);
                }

                f[i][j][h][0]=max(f[i][j][h][0],f[i-1][j][h][0]);
                f[i][j][h][0]=max(f[i][j][h][0],f[i][j-1][h][0]);
                f[i][j][h][0]=max(f[i][j][h][0],f[i-1][j][h][1]);
                f[i][j][h][0]=max(f[i][j][h][0],f[i][j-1][h][1]);
            }
        }
    }

    int ans=0;
    for(int i=1; i<=n; i++) for(int j=1; j<=m; j++)
            ans=max(ans,f[i][j][k][0]),ans=max(ans,f[i][j][k][1]);
    printf("%d\n",ans);

    return 0;
}

 

posted @ 2016-09-09 21:29  Fighting_Heart  阅读(144)  评论(0编辑  收藏  举报