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/