关闭

[CodeM初赛A轮]B

455人阅读 评论(1) 收藏 举报
分类:

题解

设dp f[i1,i2,j1,j2]表示选出A串的[i1,i2]以及B串的[j1,j2]能否组成回文串。
dp转移显然。
但是边界比较麻烦。
考虑先做dp fa[i,j]和fb[i,j]分表表示A串的[i,j]和B串的[i,j]是不是回文串,然后瞎枚举弄出一些f的初值。
回文串完全在一个串中也要判断。
有点坑QAQ
详见代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
const int maxn=50+10,inf=100000000;
char a[maxn],b[maxn];
int fa[maxn][maxn],fb[maxn][maxn],f[maxn][maxn][maxn][maxn];
int i,j,i1,i2,jj1,j2,k,l,t,n,m,ca,ans;
int main(){
    scanf("%d",&ca);
    while (ca--){
        scanf("%s",a+1);
        scanf("%s",b+1);
        n=strlen(a+1);m=strlen(b+1);
        fo(i,0,n)
            fo(j,0,n)
                fa[i][j]=-inf;
        fo(i,0,m)
            fo(j,0,m)
                fb[i][j]=-inf;
        fo(i1,0,n)
            fo(i2,0,n)
                fo(jj1,0,m)
                    fo(j2,0,m)
                        f[i1][i2][jj1][j2]=-inf;
        fo(i,1,n)
            fo(j,1,m)
                if (a[i]==b[j]) f[i][i][j][j]=2;
        ans=0;
        fo(i,1,n) fa[i][i]=1;
        fo(i,1,n-1) 
            if (a[i]==a[i+1]) fa[i][i+1]=2;
        fd(i,n,1)
            fo(j,1,n)
                if (fa[i][j]!=-inf){
                    t=fa[i][j];
                    ans=max(ans,t);
                    if (i>1&&j<n&&a[i-1]==a[j+1]) fa[i-1][j+1]=t+2;
                    fo(k,1,m){
                        if (j<n&&b[k]==a[j+1]) f[i][j+1][k][k]=t+2;
                        if (i>1&&b[k]==a[i-1]) f[i-1][j][k][k]=t+2;
                        if (k<m&&b[k]==b[k+1]) f[i][j][k][k+1]=t+2;
                    }
                }
        fo(i,1,m) fb[i][i]=1;
        fo(i,1,m-1) 
            if (b[i]==b[i+1]) fb[i][i+1]=2;
        fd(i,m,1)
            fo(j,1,m)
                if (fb[i][j]!=-inf){
                    t=fb[i][j];
                    ans=max(ans,t);
                    if (i>1&&j<m&&b[i-1]==b[j+1]) fb[i-1][j+1]=t+2;
                    fo(k,1,n){
                        if (j<m&&a[k]==b[j+1]) f[k][k][i][j+1]=t+2;
                        if (i>1&&a[k]==b[i-1]) f[k][k][i-1][j]=t+2;
                        if (k<n&&a[k]==a[k+1]) f[k][k+1][i][j]=t+2;
                    }
                }
        fd(i1,n,1)
            fo(i2,1,n)
                fd(jj1,m,1)
                    fo(j2,1,m)
                        if (f[i1][i2][jj1][j2]!=-inf){
                            t=f[i1][i2][jj1][j2];
                            ans=max(ans,t);
                            if (ans==6){
                                t=t;
                            }
                            if (i1>1&&i2<n&&a[i1-1]==a[i2+1]) f[i1-1][i2+1][jj1][j2]=t+2;
                            if (jj1>1&&j2<m&&b[jj1-1]==b[j2+1]) f[i1][i2][jj1-1][j2+1]=t+2;
                            if (i1>1&&j2<m&&a[i1-1]==b[j2+1]) f[i1-1][i2][jj1][j2+1]=t+2;
                            if (i2<n&&jj1>1&&b[jj1-1]==a[i2+1]) f[i1][i2+1][jj1-1][j2]=t+2;
                        }
        printf("%d\n",ans);
    }
}
0
0
查看评论

「美团 CodeM 初赛 Round A」二分图染色 容斥原理

题目链接点这里 首先绿色不用管 然后只有2种颜色,很显然需要用容斥原理求,先算全部的数量,然后容斥减去不合法的数目 我们n个点设单种颜色的方案数为F(n),所以2种颜色的方案数就是F(n)^2(包含不合法), 先看直接列出来的式子: #include #includ...
  • qq_30927651
  • qq_30927651
  • 2017-06-21 13:22
  • 312

[LOJ#6159][美团 CodeM 初赛 Round A][暴力即正解]最长树链

枚举每一个质数,权值是这个质数的倍数的节点设为1,否则为0,那么最长长链的长度就是点权为1的点构成的最长的链。当然不用枚举所以质数,因为每个数最多有log个不同的质因数,所以只要把所有点权质因数分解,枚举出现的质数就可以了。枚举质数后dfs,复杂度是nlogn的,因为每个点有log个不同的质因数,也...
  • Coldef
  • Coldef
  • 2017-07-06 00:47
  • 398

loj #6164. 「美团 CodeM 初赛 Round A」数列互质

莫队==每次维护每个数出现的次数,再上链表维护出现次数的次数。 发现不同的出现次数最多根号n个,因为要出现次数有不同的x个,至少要有x*(x-1)/2个数。然后考虑每次询问暴力枚举。 先把k分解成质因数,不超过logk个,分解时要判定大质数,不然GG 对于每个出现次数暴力验证,复杂度 #incl...
  • qq_35205305
  • qq_35205305
  • 2017-07-31 15:49
  • 103

codeM初赛B轮A题

[编程题] 黑白树 时间限制:1秒 空间限制:32768K 一棵n个点的有根树,1号点为根,相邻的两个节点之间的距离为1。树上每个节点i对应一个值k[i]。每个点都有一个颜色,初始的时候所有点都是白色的。 你需要通过一系列操作使得最终每个点变成黑色。每次操作需要选择一个节点i,i...
  • u010770184
  • u010770184
  • 2017-06-27 11:25
  • 118

[CodeM初赛A轮]A

题解看懂题意题。#include<cstdio> #include<algorithm> #include<cmath> #define fo(i,a,b) for(i=a;i<=b;i++) #define fd(i,a,b) for(i=a;i>=...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2017-06-18 22:12
  • 296

codeM 初赛b轮 子串

给出一个正整数n,我们把1..n在k进制下的表示连起来记为s(n,k),例如s(16,16)=123456789ABCDEF10, s(5,2)=11011100101。现在对于给定的n和字符串t,我们想知道是否存在一个k(2 ≤ k ≤ 16),使得t是s(n,k)的子串。  输入...
  • Swordsman___DDZ
  • Swordsman___DDZ
  • 2017-06-25 20:36
  • 106

【loj6162】「美团 CodeM 初赛 Round A」身体训练

题目描述 美团外卖的配送员用变速跑的方式进行身体训练。 他们训练的方式是:nnn个人排成一列跑步,前后两人之间相隔 uuu 米,每个人正常速度均为 vvv 米/秒。 当某个配送员排在最后的时候,他需要以当时自己的最高速度往前跑,直到超过排头的人 uuu 米,然后降回到原始速度 vvv 米/秒。每个...
  • w_yqts
  • w_yqts
  • 2017-12-23 12:56
  • 163

[CodeM初赛A轮]C

题解T在max和min之间无解。 考虑二分答案,然后判定很简单。 要注意一些坑点,比如解出来的体积小于0,以及没有进行任何二分判定等。 我的方法没过样例,但是过了这题……#include<cstdio> #include<algorithm> #include<c...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2017-06-18 22:17
  • 353

[CodeM初赛A轮]E

题解大小点分治。 出现次数大于阈值的,处理前缀和,然后暴力枚举一个询问判断。 出现次数小于阈值的,跑莫队,维护每个数出现次数,以及每种出现次数的数的个数,然后询问可以暴力枚举出现次数。#include<cstdio> #include<algorithm> #define...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2017-06-18 22:20
  • 415

[CodeM初赛A轮]D

题解用sqrt(a)/log a的时间分解质因数。 枚举一个质因数x,所有x的倍数节点打标记。 对于每一个被标记的联通块求直径。#include<cstdio> #include<algorithm> #include<map> #define fo(i,a,...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2017-06-18 22:18
  • 327
    个人资料
    • 访问:359784次
    • 积分:11984
    • 等级:
    • 排名:第1484名
    • 原创:815篇
    • 转载:4篇
    • 译文:0篇
    • 评论:212条
    最新评论
    文章分类