ICode9

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

CF1463F Max Correct Set

2022-08-04 15:02:09  阅读:147  来源: 互联网

标签:Set int Max 状压 CF1463F max 最优 define


题意

现求一个集合 \(S\subseteq\{1,2,\cdots,n\}\),要求满足任意两个在此集合内的数 \(a,b\),它们的差 \(|a-b|\not ={x}\) 并且 \(|a-b|\not ={y}\)。求集合 \(S\) 的最大大小。

Solution

感觉 \(n\) 很大,\(x,y\) 很小,总感觉就是状压。

界外,首先可以想到暴力的状压,就是你考虑当前数能不能选只和前面的 \(\max(x,y)\) 个数有关,所以状压一下前面 \(\max(x,y)\) 个数就可以了。但是这个东西是 \(O(2^{\max(x,y)}n)\) 的,非常 GG 啊。

\(\color{red}{\bigstar}\) 如果没什么思路可以从特殊情况考虑起,就是如果有 \(x=y\) 成立,这里可以怎么方便地来做。

容易想到,直接按照长度为 \(x\) 分成若干段,奇数段全部是 \(1\),偶数段全部是 \(0\)。这样肯定是最大的。然后来考虑这其实以 \(2x\) 为循环节来构造一组最优解。大胆猜测,当 \(x\not= y\) 时,有同样的结论,即存在一个以 \(x+y\) 为循环节的最优解。

这样的话,我们暴力做前 \(x+y\) 个的结果,然后把这一区间的最优结果乘上最终能贡献几段来 dp。复杂度是 \(O(2^{\max(x+y)}(x+y))\)。

这样构造凭什么一定合法?我们已经保证了每一块内是合法的,也就是我们只担心两块间有两个位置不合法,我们假设是 \(j-i=x\),那么会有 \(i-j+(x+y)=y\),这样子 \(x\) 和 \(y\) 肯定不会同时为 \(1\)。那这样为什么是最优呢?如果在固定了初始的 \(x+y\) 个位置之后,如果后面出现了更优的方式,直接替换掉肯定会变优。(但是这只是粗略的想法,具体证法狗都不证

Code

// Problem: CF1463F Max Correct Set
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF1463F
// Memory Limit: 3100 MB
// Time Limit: 250000 ms

#include<bits/stdc++.h>
#define ll long long
#define inf (1<<30)
#define INF (1ll<<60)
#define pb emplace_back
#define pii pair<int,int>
#define mkp make_pair
#define fi first
#define se second
#define all(a) a.begin(),a.end()
#define siz(a) (int)a.size()
#define clr(a) memset(a,0,sizeof(a))
#define rep(i,j,k) for(int i=(j);i<=(k);i++)
#define per(i,j,k) for(int i=(j);i>=(k);i--)
#define pt(a) cerr<<#a<<'='<<a<<' '
#define pts(a) cerr<<#a<<'='<<a<<'\n'
// #define int long long
using namespace std;
int dp[2][(1<<22)+5];
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int n,x,y,m,M;cin>>n>>x>>y;m=x+y;M=max(x,y);
	int op=1,lmt=(1<<M)-1;
	rep(i,1,m){
		op^=1;
		memset(dp[op],0,sizeof(dp[op]));
		rep(j,0,lmt){
			dp[op][(j<<1)&lmt]=max(dp[op][(j<<1)&lmt],dp[op^1][j]);
			if(!((j>>(x-1))&1)&&!((j>>(y-1))&1))
			dp[op][(j<<1|1)&lmt]=max(dp[op][(j<<1|1)&lmt],
			dp[op^1][j]+n/m+(n%m>=i));
		}
	}
	int ans=0;
	rep(i,0,(1<<M)-1) ans=max(ans,dp[op][i]);
	cout<<ans<<'\n';
	return 0;
}

标签:Set,int,Max,状压,CF1463F,max,最优,define
来源: https://www.cnblogs.com/ZCETHAN/p/16550565.html

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

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

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

ICode9版权所有