Bookshelves

Bookshelves

https://ac.nowcoder.com/acm/problem/112786

题意

你有 本书,每本书有一个权值 .你要将这 本书分到 个书架上,要求你分组之后的每组权值之和的按位与的值最大。

思路

位运算啊,按位考虑。贪心的从高位到低位的使得此位值为 。我们就可以枚举最后的答案,从大到小,然后依次 一下。我们设计 方程: 。表示在前 个分为了 组是否成立,最后成立条件就是

代码

#include<bits/stdc++.h>
#define int long long
const int N=1e3+5,INF=0x3f3f3f3f,mod=998244353;
using namespace std;

int n,k,ans=0;
int w[N],sum[N];
int dp[N][N];

inline int read()
{
    register int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}

int qpow(int a,int b)
{
    int ans=1;
    while(b){if(b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;}
    return ans;
}

bool check(int x)
{
    memset(dp,0,sizeof(dp));
    dp[0][0]=1;
    for(int i=1;i<=k;i++)
     for(int j=1;j<=n;j++)
      for(int m=0;m<j;m++)
       dp[i][j]|=dp[i-1][m]&(((sum[j]-sum[m])&x)==x);
    return dp[k][n];
}

signed main()
{
    n=read();k=read();
    for(int i=1;i<=n;i++)    w[i]=read(),sum[i]=sum[i-1]+w[i];
    for(int i=60;i>=0;i--)
    {
        int mid=ans|(1LL<<i);
        if(check(mid))
            ans|=(1LL<<i);
    }
    printf("%lld",ans);
    return 0;
}
全部评论

相关推荐

09-23 15:37
门头沟学院 Java
打工的隙間術士:写null,体现我们的专业素养😡
我的秋招日记
点赞 评论 收藏
分享
牛客83265014...:完了,连现在都没开始面,13号投的是不是晚了
秋招的第一个offer,...
点赞 评论 收藏
分享
如题,求问华为1145和25定律是什么意思?刷到好多人说这个东西了,不知道什么意思
我能加班:如果你在主管面试完当天晚上11点45分收到面试反馈邮件的话,大概率是通过主管面试了。25小时是指在你主管面完成收到短信后的25小时你可以在官网查到你是不是通过。 应该是这样
点赞 评论 收藏
分享
评论
6
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务