Jzoj 4889NOIP2016提高A组集训第14场11.12暴力贪心最长公共回文子序列
Posted SSL_ZZL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jzoj 4889NOIP2016提高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暴力贪心最长公共回文子序列的主要内容,如果未能解决你的问题,请参考以下文章