定义为前个书分成组的最大价值

这么转移是有后效性的

价值不是越大越好

观察到价值计算是与运算,可以一位一位单独考虑

比如,如果每组都能凑齐,那这一位上必然是

然后考虑能否凑齐,但是同时也要凑齐...

就这样一位一位去判断

还是比较显然的....

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 59;
int f[maxn][maxn],a[maxn],k,n,pre[maxn];
bool ok(int x,int y){
    return ((x&y)==x);
}
bool isok(int x)
{
    memset( f,0,sizeof f);
    for(int i=1;i<=n;i++)    f[i][1] = ok(x,pre[i]);
    for(int i=2;i<=n;i++)
    {
        int limit = min( i,k );
        for(int j=2;j<=limit;j++)//分组情况 
        for(int q=1;q<i;q++)
            f[i][j] |= ( f[q][j-1]&ok(x,pre[i]-pre[q]) );
    }
    return f[n][k];
}
signed main()
{
    cin >> n >> k;
    for(int i=1;i<=n;i++)    cin >> a[i], pre[i] = pre[i-1]+a[i];
    //定义f[i][j]为前i本书分成j个书柜的最大价值...
    //这样肯定是有后效性的,因为不是越大越好
    int base = ((int)1<<61), ans = 0;
    //是否可能保持每组都有base呢? 
    for(int i=0;i<=61;i++)
    {
        if( isok( ans+base ) )    ans += base;
        base /= 2;
    }
    cout << ans;
}