[cf1463F]Max Correct Set
记$l=a+b,P_{i}$表示$i$是否被选入$S$,则有以下结论——
结论1:若$P_{i}=P_{i+l}$且$S_{0}=\{i\mid 1\le i\le l,P_{i}=1\}$合法,则$S$也合法
反证法,若存在$x,y\in S$使得$|x-y|=a$或$b$,不妨假设$x<y$
设$x=l\cdot x_{0}+r_{x},y=l\cdot y_{0}+r_{y}$(其中$1\le r_{x},r_{y}\le l$),显然$y_{0}=x_{0}$或$x_{0}+1$
若为前者,即$r_{y}-r_{x}=a$或$b$;若为后者,即$r_{y}+l-r_{x}=a$或$b$,进而$r_{x}-r_{y}=a$或$b$
由于$P_{i}=P_{i+l}$,因此$a,b\in S_{0}$,进而与$
结论2:存在一组最优解满足$P_{i}=P_{i+l}$
任取一组最优解$P_{i}$,考虑对其调整:
设$n=l\cdot n_{0}+r_{n}$(其中$0\le r_{n}<l$),进而将其划分为$2l+1$段,长度分别为$r_{n},l-r_{n},r_{n},l-r_{n},...,r_{n}$
记$a_{i}$为第$i$段中1的个数(下标为$[0,2l]$),考虑以第$i$段和第$i+1$段为循环节(其余均改为与其同奇偶段的情况)
反证法,若不存在满足$P_{i}=P_{i+l}$的最优解,即$\begin{cases}\forall 0\le i\le l,(l+1)a_{2i}+l\cdot a_{2i+1}>\sum_{i=0}^{2l}a_{i}\\\forall 1\le i\le l,(l+1)a_{2i-1}+l\cdot a_{2i}> \sum_{i=0}^{2l}a_{i}\end{cases}$
对于$x\equiv 0(mod\ 2)$,将上式的$i\in [0,\frac{x}{2})$和下式的$i\in (\frac{x}{2},l]$求和,即得到
$$
\sum_{i=0}^{2l}(l+[i\equiv 0(mod\ 2)])a_{i}-(l+1)a_{x}>l\sum_{i=0}^{2l}a_{i}\\
(l+1)a_{x}<\sum_{0\le i\le l}a_{2i}
$$
将该式对所有$x=0,2,...,2l$求和,显然矛盾,即得证
根据上述两个结论,直接状压dp即可(存储前$\max(x,y)$个数是否选入$S$)
时间复杂度为$o(l\cdot 2^{\max(x,y)})$,可以通过
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 22 4 int n,l,x,y,ans,cnt[N<<2],f[2][1<<N]; 5 int main(){ 6 scanf("%d%d%d",&n,&x,&y),l=x+y; 7 if (x>y)swap(x,y); 8 for(int i=1;i<=l;i++)cnt[i]=n/l+(i<=n%l); 9 f[0][0]=0; 10 for(int i=0,p=1;i<l;i++,p^=1){ 11 memset(f[p],0,sizeof(f[p])); 12 for(int j=0;j<(1<<y);j++){ 13 int jj=(j<<1)%(1<<y); 14 f[p][jj]=max(f[p][jj],f[p^1][j]); 15 if (((j>>x-1)&1)||((j>>y-1)&1))continue; 16 f[p][jj|1]=max(f[p][jj|1],f[p^1][j]+cnt[i+1]); 17 } 18 } 19 for(int i=0;i<(1<<y);i++)ans=max(ans,f[l&1][i]); 20 printf("%d\n",ans); 21 return 0; 22 }