Codeforces Round 338 C

来源:互联网 发布:c语言中的int 编辑:程序博客网 时间:2024/06/08 19:56

题目链接:http://codeforces.com/contest/615/problem/C
题解:

我们可以直接跑dp,预处理dp1[i][j],表示匹配到s串的i位置,t串的j位置时候,最多可以往前跳dp1[i][j]个字符。

其实这个就是最长公共前缀的dp。

跑完之后,我们就可以跑第二个dp了,dp[i]表示以t的i位置结尾所需要的最少次数。

很显然dp[i] = max(dp[i],dp[i-dp1[j][i]]+1);

然后记录一下过程,倒着跑一下DP,把路径输出就好了。
第二种方法是直接暴力匹配

#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<queue>#include<math.h>#include<stdlib.h>#include<vector>#include<map>#include<string>using namespace std;#define ll long long#define For(i,n) for(int i=1;i<=n;i++)#define Dor(i,n) for(int i=n;i>=1;i--)#define s(n) scanf("%d",&n)#define p(n) printf("%d\n",n)//#define maxn 200000+10#define ms(n) memset(n,0,sizeof(n))#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1const double eps=1e-8;const int inf=0x3f3f3f3f;const int maxn=2e3+115;char t[maxn],s[maxn],ss[maxn];int ans[maxn][2];int main(){    scanf("%s%s",s,t);    strcpy(ss,s);    int kk=0;    //cout<<" ==  "<<ss<<endl;    int ls=strlen(s);int lt=strlen(t);int nextpos,maxlen;    for(int i=0;i<ls;i++){        ss[i]=s[ls-i-1];    }    //cout<<"   "<<ss<<endl;    int p1,p2;    for(int i=0;i<lt;){        nextpos=-1;        for(int j=0;j<ls;j++){            int k=j;int next=i;            while(k<ls&&next<lt&&t[next]==s[k])               k++,next++;            if(next>nextpos){nextpos=next;p1=j+1;p2=k;}        }        for(int j=0;j<ls;j++){            int k=j;int next=i;            while(k<ls&&next<lt&&t[next]==ss[k])               k++,next++;            if(next>nextpos){nextpos=next;p1=ls-j;p2=ls-k+1;}        }        if(i==nextpos) {            puts("-1");return 0;        }        i=nextpos;ans[kk][0]=p1;ans[kk++][1]=p2;    }    printf("%d\n",kk);    for(int i=0;i<kk;i++){        printf("%d %d\n",ans[i][0],ans[i][1]);    }    return 0;}
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<queue>#include<math.h>#include<stdlib.h>#include<vector>#include<map>#include<string>using namespace std;#define ll long long#define For(i,n) for(int i=1;i<=n;i++)#define Dor(i,n) for(int i=n;i>=1;i--)#define s(n) scanf("%d",&n)#define p(n) printf("%d\n",n)//#define maxn 200000+10#define ms(n) memset(n,0,sizeof(n))#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1const double eps=1e-8;const int inf=0x3f3f3f3f;const int maxn=2e3+115;char t[maxn],s[maxn],ss[maxn];int ans[maxn][2];int ls,lt;int dp1[maxn][maxn],dp2[maxn][maxn],dp[maxn];int pre[maxn];void debug(){    for(int i=1;i<=ls;i++){        for(int j=1;j<=lt;j++){            cout<<"i="<<i<<" j="<<j<<" dp= "<<dp1[i][j]<<endl;        }    }}int main(){    scanf("%s%s",s+1,t+1);    ls=strlen(s+1);lt=strlen(t+1);    for(int i=1;i<=ls;i++){        ss[i]=s[ls-i+1];    }    for(int i=1;i<=2100;i++) dp[i]=inf;    //cout<<ss+1<<endl;    for(int i=1;i<=ls;i++){        for(int j=1;j<=lt;j++){            if(s[i]==t[j]){                dp1[i][j]=dp1[i-1][j-1]+1;            }            if(ss[i]==t[j]){                dp2[i][j]=dp2[i-1][j-1]+1;            }        }    }    //debug();    for(int i=1;i<=lt;i++){        for(int j=1;j<=ls;j++){            if(dp1[j][i]&&dp[i]>dp[i-dp1[j][i]]+1){                dp[i]=min(dp[i],dp[i-dp1[j][i]]+1);                pre[i]=i-dp1[j][i];            }            if(dp2[j][i]&&dp[i]>dp[i-dp2[j][i]]+1){                dp[i]=min(dp[i],dp[i-dp2[j][i]]+1);                pre[i]=i-dp2[j][i];            }        }    }    if(dp[lt]>=inf) return puts("-1");    printf("%d\n",dp[lt]);    int kk=0;    int sum=dp[lt];int now=lt;    while(sum--){        for(int i=1;i<=ls;i++){            if(now-pre[now]==dp1[i][now]){               ans[sum][0]=i-dp1[i][now]+1;               ans[sum][1]=i;               now=pre[now];break;              }            if(now-pre[now]==dp2[i][now]){                ans[sum][0]=ls-i+dp2[i][now];                ans[sum][1]=ls-i+1;                now=pre[now];break;            }        }    }    for(int i =0;i<dp[lt];i++){        printf("%d %d\n",ans[i][0],ans[i][1]);    }    return 0;}
0 0
原创粉丝点击