Bookshelves
按位贪心然后dp去验证,实在是太妙了,,,
从高到底,如果高位能选的话优先选高位(低位所有的都选上还是比它小),
接下来就是dp验证当前解是否可行了,定义dp[i][j]表示用前i本书放在前j个书架上是否可以得到当前答案满足要求。
然后不断更新合法答案即可,整体复杂度
/* Author : lifehappy */ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 55; int n, k; ll a[N]; bool f[N][N]; bool judge(ll x) { memset(f, 0, sizeof f); f[0][0] = 1; for (int r = 1; r <= n; r++) { for (int i = 1; i <= k; i++) { for (int l = 0; l < r; l++) { f[r][i] |= f[l][i - 1] & (((a[r] - a[l]) & x) == x); } } } return f[n][k]; } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); scanf("%d %d", &n, &k); for (int i = 1; i <= n; i++) { scanf("%lld", &a[i]); a[i] += a[i - 1]; } ll ans = 0; for (int i = 60; i >= 0; i--) { ll res = ans | 1ll << i; if (judge(res)) { ans = res; } } printf("%lld\n", ans); return 0; }