题目链接
题意:
给定一个字符串,可以任意选择其中一段连续的,将其字母顺序从后往前倒置,如一段子序列abcd可变成dcba。求其中没有重复字母的最长子序列长度。
样例:
输入:
abacaba
输出:
3
输入:
abcdecdf
输出:
6
输入:
aabbcc
输出:
3
思路:
只需要找到两个没有相同字母的子序列,使其和最大即可。
状压dp 写法见代码注释
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1000006, maxm = (1 << 20) + 5;
char s[maxn];
int dp[maxm], vis[22];
int main()
{
int i, j;
scanf("%s", s);
int len = strlen(s);
for (i = 0; i < len; i++)
{
memset(vis, 0, sizeof(vis));
int cnt = 0;
int x = 0;
for (j = i; j < len; j++)
{
if (vis[s[j] - 'a'] == 1)
break;
else
{
vis[s[j] - 'a'] = 1;
cnt++;
x = x | 1 << (s[j] - 'a');
dp[x] = cnt;
}
}
}
for (i = 0; i < 1 << 20; i++)
{
for (j = 0; j < 20; j++)
{
if (i & (1 << j))
dp[i] = max(dp[i], dp[i ^ (1 << j)]);
}
} //记录每个集合的所有子集中最大的数
int ans = 0;
for (i = 0; i < 1 << 20; i++)
{
ans = max(ans, dp[i] + dp[i ^ ((1 << 20) - 1)]); //dp[i]+dp[i]的补集
}
printf("%d\n", ans);
}