Loading

CF1463F Max Correct Set

题意

现求一个集合 \(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;
}
posted @ 2022-08-04 14:49  ZCETHAN  阅读(17)  评论(0编辑  收藏  举报