E题题解
CCA的区间
https://ac.nowcoder.com/acm/contest/11168/E
重点:可以反转一个区间代表着可以将任意两个连续的区间拼接在一起
那么我们就转化为找到两个区间没有交集,他们的和最大。
可以用dp【i】来表示最后一个数为a【i】的所能组成一段的最大值,我们可以从i位暴力往前找,最多找到23个数就会出现交集。
然后进行sosdp(不难的,学一下)找到每个数的子集的最大值,然后暴力求解。
int dp[maxn];
int sos[maxn];
int a[maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
dp[i]=a[i];
sos[dp[i]]=dp[i];
for(int j=i-1;j>0;j--)
{
if(dp[i]&a[j]) break;
dp[i]+=a[j];
sos[dp[i]]=dp[i];
}
}
for(int i=0;i<=23;i++)
{
for(int j=0;j<(1<<24);j++)
{
if(j&(1<<i)) sos[j]=max(sos[j],sos[j^(1<<i)]);
}
}
int up=1<<24;
up--;
int ans=0;
for(int i=0;i<=up;i++)
{
ans=max(ans,sos[i]+sos[up^i]);
}
printf("%d\n",ans);
}
}