CF981D Bookshelves 题解

分析

按位贪心。

由于高位的 \(1\) 优于低位的所有 \(1\),所以考虑一个过程check(x),表示是否能够在保证更高位的 \(1\) 不会减少的情况下,使得当前这一位为 \(1\)

\(f(i,j)\) 表示前 \(i\) 本书,划分成 \(j\) 段是否可行。 \[ f(i,j) = \operatorname{OR}_{k=0}^{i-1} f(k,j-1) \operatorname{AND} [sum(k+1,i) \& x = x] \] 如果 \(sum(k+1,i) \& x = x\),那么说明这一段在满足之前所有 \(1\) 的情况下还能满足这一位是 \(1\)。至于其他位则不必关心。

CODE

const int N=55;
int n, k, s[N], f[N][N];
int check(int x) {
	SET(f,0);
	f[0][0]=1;
	for(int i=1;i<=n;++i) {
		for(int j=1;j<=k;++j) for(int k=0;k<i;++k) {
			f[i][j]|=f[k][j-1]&(((s[i]-s[k])&x)==x);
		}
	}
	return f[n][k];
}
signed main() {
	n=read(), k=read();
	for(int i=1;i<=n;++i) s[i]=s[i-1]+read();
	int ans=0;
	for(int i=62;~i;--i) {
		if(check(ans|(1ll<<i))) ans|=(1ll<<i);
	}
	printf("%lld\n",ans);
}

CF981D Bookshelves 题解
https://yozora0908.github.io/2022/cf981d-solution/
作者
yozora0908
发布于
2022年10月23日
许可协议