题目
n个数选k个,使它们的或最大
n<=1e5 k>=20 ai<=1e6
题解
从高向低位或,
每个数至少产生一位的贡献,所以最多20个数
贪心地使或的数最大即可
由于或没有副作用可以优先或大的数
k个最大一定可以由k-1个最大的转移而来
k<=20也可以做,复杂度O(min(k,最大的数的位数)*n)
心得
QAQ第一次打Arab的场体验极差……
还得打开文件开始不知道然后就Wa了……
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e6+10;
int t,n,k;
int a[maxn];
int mx,res;
inline int rd(){
int num=0,w=0;char ch=0;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch)){num=(num<<3)+(num<<1)+(ch^48);ch=getchar();}
return w? -num: num;
}
int main()
{
freopen("looking.in","r",stdin);
t=rd();
while(t--)
{
res=0;
n=rd(),k=rd();
for(int i=0;i<n;++i)
a[i]=rd();
for(int i=20;i>=0;--i)
{
mx=res;
for(int j=0;j<n;++j)
{
if(!(a[j]>>i&1))continue;
if((a[j]|res)>mx)mx=a[j]|res;
}
res=mx;
}
printf("%d\n",res);
}
return 0;
}
本文探讨了一种算法策略,用于从n个整数中选择k个数,以使这些数的按位或运算结果最大。通过从高位到低位贪婪地选择能够提供最大贡献的数,确保了所选k个数的或运算结果尽可能大。此策略适用于k小于等于20的情况,复杂度为O(min(k, 最大的数的位数) * n)。
4100

被折叠的 条评论
为什么被折叠?



