纪念卡常把自己卡死的一次自闭模拟赛

QWQ

一开始看这个题,以为是个图论,仔细一想,貌似可以直接dp啊。

首先,因为规则只有从两个变为1个,貌似可以用类似区间\(dp\)的方式来\(check\)一段区间能不能合成某一个字母!

那我们定义\(f[i][j][k]\)表示第一个串,\([l,r]\)区间,是否可以合成\(k\)这个字母

然后转移的时候,枚举区间,枚举规则,枚举断点,满足\(f[l][k][p1]==1\)且\(f[k+1][r][p2]==1\) 才能使当前状态合法。

其中\(p1,p2\)表示当前规则的两个字母

for (int i=1;i<=n;i++) f[i][i][cc(s[i])]=1;
for (register int i=2;i<=n;++i)
for (register int l=1;l<=n-i+1;++l)
{
int r = l+i-1;
for (register int j=1;j<=26;++j)
{
for (register int p=1;p<=num[j];++p)
{
for (register int k=l;k<=r;++k)
{
f[l][r][j]=max(f[l][r][j],f[l][k][a[j][p].a]&f[k+1][r][a[j][p].b]);
if (f[l][r][j]) break;
}
if (f[l][r][j]) break;
}
}
}

同时定义\(g[l][r][k]\)数组表示第二个串区间\([l,r]\)能否合成k。处理和f类似。

统计答案的时候呢

还需要一个\(dp[i][j]\)表示第一个串的前i个字符和第二个串的前j个字符的最短公共祖先

那么,考虑枚举两个断点,两个串的后面两段能合成同一个字母,那么就可以从那个断点之前的状态转移过来

QWQ

详细直接看代码吧

memset(dp,127/3,sizeof(dp));
dp[0][0]=0;
for (register int i=1;i<=nn;++i)
{
for (register int k=1;k<=n;++k)
{
for (register int j=1;j<=i;++j)
for (register int p=1;p<=k;++p)
{
if (dp[j-1][p-1]==dp[maxn-3][maxn-3]) continue;
bool flag=false;
for (register int o=1;o<=26;o++)
if (g[j][i][o] && f[p][k][o]) flag=true;
if (flag) dp[i][k]=min(dp[i][k],dp[j-1][p-1]+1);
}
}
}

最后复杂度就是\(O(n^4*26)\)

我也不知道为啥能跑过啊

qwqwqwq

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk makr_pair
#define ll long long
#include<ctime>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 110;
struct Node{
int a,b;
};
Node a[maxn][maxn];
int num[maxn];
int f[maxn][maxn][maxn];
int g[maxn][maxn][maxn];
int n,m;
char s[maxn];
char ss[maxn];
int nn;
string ans;
int dp[maxn][maxn];
inline int cc(char c)
{
return c-'a'+1;
}
int main()
{
scanf("%s",s+1);
scanf("%s",ss+1);
s[0]=ss[0]='*';
n=strlen(s+1);
nn=strlen(ss+1);
m=read();
for (register int i=1;i<=m;++i)
{
char ymh[10];
scanf("%s",ymh+1);
int now = ymh[1]-'a'+1;
num[now]++;
a[now][num[now]].a = ymh[4]-'a'+1;
a[now][num[now]].b = ymh[5]-'a'+1;
}
for (int i=1;i<=n;i++) f[i][i][cc(s[i])]=1;
for (register int i=2;i<=n;++i)
for (register int l=1;l<=n-i+1;++l)
{
int r = l+i-1;
for (register int j=1;j<=26;++j)
{
for (register int p=1;p<=num[j];++p)
{
for (register int k=l;k<=r;++k)
{
f[l][r][j]=max(f[l][r][j],f[l][k][a[j][p].a]&f[k+1][r][a[j][p].b]);
if (f[l][r][j]) break;
}
if (f[l][r][j]) break;
}
}
}
for (int i=1;i<=nn;i++) g[i][i][cc(ss[i])]=1;
for (register int i=2;i<=nn;i++)
for (register int l=1;l<=nn-i+1;++l)
{
int r = l+i-1;
for (register int j=1;j<=26;++j)
{
for (register int p=1;p<=num[j];++p)
{
for (register int k=l;k<=r;++k)
{
g[l][r][j]=max(g[l][r][j],g[l][k][a[j][p].a]&g[k+1][r][a[j][p].b]);
if (g[l][r][j]) break;
}
if (g[l][r][j]) break;
}
}
}
memset(dp,127/3,sizeof(dp));
dp[0][0]=0;
for (register int i=1;i<=nn;++i)
{
for (register int k=1;k<=n;++k)
{
for (register int j=1;j<=i;++j)
for (register int p=1;p<=k;++p)
{
if (dp[j-1][p-1]==dp[maxn-3][maxn-3]) continue;
bool flag=false;
for (register int o=1;o<=26;o++)
if (g[j][i][o] && f[p][k][o]) flag=true;
if (flag) dp[i][k]=min(dp[i][k],dp[j-1][p-1]+1);
}
}
}
if(dp[nn][n]==dp[maxn-3][maxn-3]) dp[nn][n]=-1;
cout<<dp[nn][n]<<endl;
return 0;
}

CF49E Common ancestor(dp+dp+dp)的更多相关文章

  1. [PAT] 1143 Lowest Common Ancestor(30 分)

    1143 Lowest Common Ancestor(30 分)The lowest common ancestor (LCA) of two nodes U and V in a tree is ...

  2. [CF49E]Common ancestor

    [CF49E]Common ancestor 题目大意: 有两个由小写字母构成的字符串\(S\)和\(T(|S|,|T|\le50)\).另有\(n(n\le50)\)个形如\(a\to bc\)的信 ...

  3. 【Aizu2292】Common Palindromes(回文树)

    [Aizu2292]Common Palindromes(回文树) 题面 Vjudge 神TMD日语 翻译: 给定两个字符串\(S,T\),询问\((i,j,k,l)\)这样的四元组个数 满足\(S[ ...

  4. PAT A1143 Lowest Common Ancestor (30 分)——二叉搜索树,lca

    The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U ...

  5. 【POJ3415】 Common Substrings(后缀数组|SAM)

    Common Substrings Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤ ...

  6. POJ 1330 Nearest Common Ancestors(Targin求LCA)

    传送门 Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26612   Ac ...

  7. [PAT] 1143 Lowest Common Ancestor(30 分)1145 Hashing - Average Search Time(25 分)

    1145 Hashing - Average Search Time(25 分)The task of this problem is simple: insert a sequence of dis ...

  8. LeetCode 236. 二叉树的最近公共祖先(Lowest Common Ancestor of a Binary Tree)

    题目描述 给定一棵二叉树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义: “对于有根树T的两个结点u.v,最近公共祖先表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. ...

  9. ACM学习历程—HDU 3092 Least common multiple(数论 && 动态规划 && 大数)

    Description Partychen like to do mathematical problems. One day, when he was doing on a least common ...

随机推荐

  1. django1.9和mysql

    修改setting.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql',#使用mysql 'NAME': 'jiank ...

  2. 算法:实现strStr(),字符串indexOf方法

    描述 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始).如果不存在,则返回  -1. 个人思路: ...

  3. Tars | 第6篇 基于TarsGo Subset路由规则的Java JDK实现方式(下)

    目录 前言 1. 修改.tars协议文件 1.1 Java源码位置及逻辑分析 1.2 Java语言实现方式 1.3 通过协议文件自动生成代码 1.4 变更代码的路径 2. [核心]增添Subset核心 ...

  4. ipsec.conf配置文件多个保护子网解析流程

    Author       : Email         : vip_13031075266@163.com Date          : 2021.01.23 Copyright : 未经同意不得 ...

  5. 10分钟学会VS NuGet包私有化部署

    前言 我们之前实现了打包发布NuGet,但是发布后的引用是公有的,谁都可以访问,显然这种方式是不可取的. 命令版本:10分钟学会Visual Studio将自己创建的类库打包到NuGet进行引用(ne ...

  6. Vue element keyup.enter失效不起作用

    解决方式一 添加按键修饰符@keyup.enter.native 解决方式二 把事件绑定到父元素(外框),需注意多个input问题 <div @keyup.enter="login&q ...

  7. Windows phone 8 触发器使用小结

    引用空间: xmlns:ec="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expres ...

  8. 为什么不推荐Python初学者直接看项目源码

    无论是有没有其他语言的经验,入门Python都很简单.Python拥有简单直观的语法,方便的语法糖,以及丰富的第三方库.只要一个基础的Python教程,大家基本上都能无障碍的入门.在入门之后,很多人对 ...

  9. TP5多条件搜索,同时有必要条件

    $model = $this->model; // 查询是否有搜索参数 $search = input('?get.search') ? trim(input('get.search')) : ...

  10. javascript 实现php str_pad

    * 查看php.net官方手册 string str_pad ( string $input , int $pad_length [, string $pad_string = " &quo ...