【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;
}

猜你喜欢

转载自www.cnblogs.com/cjyyb/p/10574371.html