ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF888E Maximum Subsequence 题解

2022-04-07 20:03:28  阅读:143  来源: 互联网

标签:ch CF888E 题解 ans2 Subsequence ans1 size pos2 pos1


首先看完本题,最直接的想法就是——爆搜!

但是, \(2^{35}\) 让我们望而却步,因此我们需要考虑一定的优化。

而本题的优化是十分经典的 折半搜索 (Meet in middle) 算法。

折半搜索的主要思路就是:将序列裂成两半搜索,然后合并答案。

对于这道题,我们首先对 \([1,\dfrac{n}{2}]\) 做一次暴力搜索, \([\dfrac{n}{2}+1,n]\) 做一次暴力搜索,统计的和存在 \(ans1,ans2\) 里面,其中不要忘记取模。

但是这样还是没有用啊?此时就要请出另一利器:尺取法

首先对 \(ans1,ans2\) 排个序,然后指定 \(pos1=1,pos2=size(ans2)\) 。

由于此时 \(ans1,ans2\) 中每个数都在 \([0,m)\) 范围内。因此我们只需要考虑 \(ans1_{pos1}+ans2_{pos2} < m\) 的结果即可。为什么不需要考虑大于 \(m\) 的?因为最大值 \(ans1_{size(ans1)}+ans2_{size(ans2)} < 2n\) ,此时对于大于 \(m\) 的和而言,\(ans1_{size(ans1)}+ans2_{size(ans2)}\) 一定是最优解,因此不需要考虑。

想清楚后代码就很简单了。

代码:

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 40 + 10;
int n, m, a[MAXN], ans1[1 << 20], ans2[1 << 20], mid, cnt1, cnt2, ans;

int read()
{
	int sum = 0, fh = 1; char ch = getchar();
	while (ch < '0' || ch > '9') {if (ch == '-') fh = -1; ch = getchar();}
	while (ch >= '0' && ch <= '9') {sum = (sum << 3) + (sum << 1) + (ch ^ 48); ch = getchar();}
	return sum * fh;
}

void dfs1(int k, int sum)
{
	if(k == mid + 1) {ans1[++cnt1] = sum; return ;}
	dfs1(k + 1, sum); dfs1(k + 1, (sum + a[k]) % m);
}

void dfs2(int k, int sum)
{
	if(k == n + 1) {ans2[++cnt2] = sum; return ;}
	dfs2(k + 1, sum); dfs2(k + 1, (sum + a[k]) % m);
}

int main()
{
	n = read(); m = read();mid = n >> 1;
	for(int i = 1; i <= n; ++i) a[i] = read();
	dfs1(1, 0); dfs2(mid + 1, 0);
	sort(ans1 + 1, ans1 + cnt1 + 1); sort(ans2 + 1, ans2 + cnt2 + 1);
	int pos1 = 1, pos2 = cnt2;
	while(pos1 <= cnt1 && pos2 >= 1)
	{
		while(ans1[pos1] + ans2[pos2] >= m) pos2--;
		ans = max(ans, ans1[pos1] + ans2[pos2]); pos1++;
	}
	printf("%d\n", max(ans, (ans1[cnt1] + ans2[cnt2]) % m));
	return 0;
}

标签:ch,CF888E,题解,ans2,Subsequence,ans1,size,pos2,pos1
来源: https://www.cnblogs.com/Plozia/p/16113971.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有