【CF981D】Bookshelves(贪心,动态规划)
【CF981D】Bookshelves(贪心,动态规划)
题面
洛谷
Codeforces
给定一个长度为\(n\)的数列,把他们划分成\(k\)段,使得每段的和的结构按位与起来最大。
题解
从高位往低位贪心,然后暴力\(dp\)就行了吧。。。
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 55
#define ll long long
inline ll read()
{
ll x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,k;ll a[MAX],s[MAX],ans;
bool f[MAX][MAX];
bool dp(ll lim)
{
for(int i=0;i<=n;++i)
for(int j=0;j<=k;++j)f[i][j]=false;
f[0][0]=true;
for(int i=1;i<=n;++i)
for(int j=0;j<i;++j)
for(int k=0;k<i;++k)
if(((s[i]-s[k])&lim)==lim)
f[i][j+1]|=f[k][j];
return f[n][k];
}
int main()
{
n=read();k=read();
for(int i=1;i<=n;++i)a[i]=read(),s[i]=s[i-1]+a[i];
for(int i=60;~i;--i)if(dp(ans|(1ll<<i)))ans|=1ll<<i;
cout<<ans<<endl;
return 0;
}