CodeForces 981D Bookshelves(dp+贪心)

D. Bookshelves
time limit per test:1 second
memory limit per test:256 megabytes
input:standard input
output:standard output

Mr Keks is a typical white-collar in Byteland.

He has a bookshelf in his office with some books on it, each book has an integer positive price.

Mr Keks defines the value of a shelf as the sum of books prices on it.

Miraculously, Mr Keks was promoted and now he is moving into a new office.

He learned that in the new office he will have not a single bookshelf, but exactly k

bookshelves. He decided that the beauty of the k

shelves is the bitwise AND of the values of all the shelves.

He also decided that he won't spend time on reordering the books, so he will place several first books on the first shelf, several next books on the next shelf and so on. Of course, he will place at least one book on each shelf. This way he will put all his books on k

shelves in such a way that the beauty of the shelves is as large as possible. Compute this maximum possible beauty.

Input

The first line contains two integers n

and k ( 1kn50

) — the number of books and the number of shelves in the new office.

The second line contains n

integers a1,a2,an, ( 0<ai<250

) — the prices of the books in the order they stand on the old shelf.

Output

Print the maximum possible beauty of k

shelves in the new office.

Examples
Input
Copy
10 4
9 14 28 1 7 13 15 29 2 31
Output
Copy
24
Input
Copy
7 3
3 14 15 92 65 35 89
Output
Copy
64
Note

In the first example you can split the books as follows:

(9+14+28+1+7)&(13+15)&(29+2)&(31)=24.

In the second example you can split the books as follows:

(3+14+15+92)&(65)&(35+89)=64.



        大致题意:给你n本书,要求你按顺序把这些书放到m个书架上面,每个书架的权值定义为书架内所有书的权值和。现在要求求这些书架权值的按位与操作和最大。

        考虑二进制的性质,最高位如果取了,肯定比不取的值大。因此,如果存在一种情况使得二进制下,某一个高位为1,那么最后结果肯定大于等于这一位为1的数字。然后,最后结果显然是可以按位分解的,具有叠加性,例如样例24=(11000)2,那么一定能够拼凑出8和16。于是我们就可以考虑从高位开始贪心累加,如果令答案这一位为1可以找到可行解,那么把这一位贡献加入答案;如果找不到可行解,那么不加入贡献。

        于是,问题变成了如何判断是否存在可行解。经过观察,可以发现这是一个典型的区间dp问题。令布尔数组dp[i][j][x]表示前i个柜子放j本书然后按位与之和为x是否可行。那么有转移方程dp[i][j][x]|=dp[i-1][k-1]&&(s[j]-s[k-1]&x)==x。最后判断dp[m][n][x]是否为1就可以知道是否存在可行解。由于x的范围很大,而实际上不需要全部求对转移方程也不影响,因此可以去掉这一维,只求解需要的值。

        实际情况下,最高位取50位并不够。具体见代码:

#include<bits/stdc++.h>
#define LL long long
using namespace std;

LL s[100],ans,n,m;
bool f[60][60];

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>s[i];
        s[i]+=s[i-1];
    }
    ans=0;
    for(LL p=1LL<<60;p>0;p>>=1)
    {
        memset(f,0,sizeof(f));
        ans|=p; f[0][0]=1;
        for(int i=1;i<=m;i++)
            for(int j=i;j<=n;j++)
                for(int k=i;k<=j;k++)
                    f[i][j]|=f[i-1][k-1]&&((s[j]-s[k-1])&ans)==ans;
        if (!f[m][n]) ans^=p;
    }
    cout<<ans<<endl;
    return 0;

}

猜你喜欢

转载自blog.csdn.net/u013534123/article/details/80479827