Jzoj 4889NOIP2016提高A组集训第14场11.12暴力贪心最长公共回文子序列

Posted SSL_ZZL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jzoj 4889NOIP2016提高A组集训第14场11.12暴力贪心最长公共回文子序列相关的知识,希望对你有一定的参考价值。

【NOIP2016提高A组集训第14场11.12】最长公共回文子序列

link

Jzoj 【4889】【NOIP2016提高A组集训第14场11.12】最长公共回文子序列


题面

Description
YJC最近在学习字符串的有关知识。今天,他遇到了这么一个概念:最长公共回文子序列。一个序列S,如果S是回文的且分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共回文子序列。YJC很聪明,他很快就学会了如何求最长公共回文子序列。他现在想把问题规模扩大一些,于是他提出了这么一个问题:给一个长度为n(1≤n≤100000)的字符串a和一个长度为m(1≤m≤20)的字符串b,求a和b的最长公共回文子序列的长度。YJC发现他不会做了,于是他来问你这个问题的答案。

Input
第一行包含一个字符串,表示字符串a。
第二行包含一个字符串,表示字符串b。

Output
一行,包含一个整数,表示a和b的最长公共回文子序列的长度。

Sample Input

aaaba
aabba

Sample Output

3

Data Constraint
对于50%的数据,满足1≤n≤100。
对于100%的数据,满足1≤n≤100000,1≤m≤20,字符串只包含小写字母。

Hint
最长公共回文子序列是aaa,长度为3。最长公共子序列是aaba,但它不是回文的。


解题思路

正解好像巨难
因为时间给了两秒,于是我采用一整个打暴力

第二个串很短,所以就暴搜出所有子序列,然后再贪心a串里有没有


Code

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

char a[100100], b[30], f[30];
int la, lb, num, ans;

bool check() {
	int i = 1, j = num;
	while(i <= j) {if(f[i] != f[j]) break; i ++, j --;}  //判断是不是回文
	if(i <= j) return 0;
	
	for(i = 1, j = 1; i <= la; i ++) {
		if(f[j] == a[i]) j ++;  //贪心
		if(j > num) break;
	}
	return (j > num);
}

void dfs(int x) {
	if(x > lb) {
		if(check()) ans = max(ans, num);
		return;
	}
	dfs(x + 1);  //暴搜出所有可能
	f[++ num] = b[x];
	dfs(x + 1);
	num --;
}

int main() {
	freopen("lcps.in", "r", stdin);
	freopen("lcps.out", "w", stdout);
	scanf("%s", a + 1);
	scanf("%s", b + 1);
	la = strlen(a + 1), lb = strlen(b + 1);
	dfs(1);
	printf("%d", ans);
}

以上是关于Jzoj 4889NOIP2016提高A组集训第14场11.12暴力贪心最长公共回文子序列的主要内容,如果未能解决你的问题,请参考以下文章

NOIP2016提高A组集训第4场11.1平衡的子集

NOIP2016提高A组集训第3场10.31高维宇宙

Jzoj4742NOIP2016提高A组模拟9.2快速幂单峰

NOIP2016提高A组集训第14场11.12随机游走

NOIP2016提高A组集训第13场11.11最大匹配

jzoj6276. noip提高组模拟1树