// dp +位处理相关 bitmask F - Yet Another Substring Reverse Codeforces Round #590 (Div. 3)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43880084/article/details/101949934

LINK-> F - Yet Another Substring Reverse

F. Yet Another Substring Reverse
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a string s consisting only of first 20 lowercase Latin letters (‘a’, ‘b’, …, ‘t’).

Recall that the substring s[l;r] of the string s is the string slsl+1…sr. For example, the substrings of “codeforces” are “code”, “force”, “f”, “for”, but not “coder” and “top”.

You can perform the following operation no more than once: choose some substring s[l;r] and reverse it (i.e. the string slsl+1…sr becomes srsr−1…sl).

Your goal is to maximize the length of the maximum substring of s consisting of distinct (i.e. unique) characters.

The string consists of distinct characters if no character in this string appears more than once. For example, strings “abcde”, “arctg” and “minecraft” consist of distinct characters but strings “codeforces”, “abacaba” do not consist of distinct characters.

Input
The only line of the input contains one string s consisting of no more than 106 characters ‘a’, ‘b’, …, ‘t’ (first 20 lowercase Latin letters).

Output
Print one integer — the maximum possible length of the maximum substring of s consisting of distinct characters after reversing no more than one its substring.

Examples
inputCopy
abacaba
outputCopy
3
inputCopy
abcdecdf
outputCopy
6
inputCopy
aabbcc
outputCopy
3
inputCopy
abcdeefc
outputCopy
6

  • __builtin_popcount(n),可以精确计算n表示成二进制时有多少个1 more

  • 代码附注释

  • 看那些大佬的代码真真觉得赏心悦目

#include<bits/stdc++.h>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);string s;
	cin>>s;vector<int>v;int len=s.length();
	for(int i=0;i<len;i++)
	{
		int k=0;
		for(int j=i;j<len;j++)
		{
			int t=s[j]-'a';
			if(k>>t&1) break;// 连续且互不相同的序列,若出现重复则退出 
			k^=1<<t;
			v.push_back(k);//k表示这个序列包含的元素   k中为1表示存在这个元素 
		}
	}
	vector<int>f(1<<20);
	for(int i=0;i<v.size();i++) f[v[i]]=__builtin_popcount(v[i]);//里面不重复元素个数的统计 
	for(int s=0;s<f.size();s++)
	{
		for(int t=0;t<20;t++)
		{
			if(s>>t&1)//想一下符合s的子列可能不存在 , 那么就用包含于它最优的子列代替 (有总比没有好吧!!)
			{
				f[s]=max(f[s],f[s^(1<<t)]);
			}
		}
	}
	int ans=0;
	for(int i=0;i<f.size();i++)
	{
		ans=max(ans,f[i]+f[((1<<20)-1)^(i)]);//两个元素绝对不重复的子列 
	}
	printf("%d\n",ans);
}

猜你喜欢

转载自blog.csdn.net/weixin_43880084/article/details/101949934