【题解】
我们设总共有m个二进制位出现过1,那么如果n-k≥m,显然所有的1都可以出现,那么答案就是把所有的数或起来。
如果n-k<m,那么因为k不超过100,ai不超过1e5,所以n不超过117,直接n*1e5的Dp即可。
Dp的方式也是多种多样,如果设f[i][j]表示前i个数字或出j最少需要几个数字,那么转移方程为f[i][j|a[i]]=min(f[i-1][j|a[i]],f[i-1][j]+1]).
1 #include2 #include 3 #include 4 #define LL long long 5 #define rg register 6 #define N 131072 7 using namespace std; 8 int n,m,k,sum,ans,a[N],f[120][N]; 9 inline int read(){10 int k=0,f=1; char c=getchar();11 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();12 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();13 return k*f;14 }15 int main(){16 n=read(); k=read();17 for(rg int i=1;i<=n;i++) a[i]=read(),sum|=a[i];18 int x=sum;19 for(rg int i=16;i;i--)if(x>=(1< =m) printf("%d\n",sum);21 else{22 for(rg int i=0;i<=n;i++)23 for(rg int j=0;j
1 #include2 #include 3 #include 4 #define LL long long 5 #define rg register 6 #define N 131072 7 using namespace std; 8 int n,m,k,sum,ans,a[N],f[120][N]; 9 inline int read(){10 int k=0,f=1; char c=getchar();11 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();12 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();13 return k*f;14 }15 int main(){16 n=read(); k=read();17 for(rg int i=1;i<=n;i++) a[i]=read(),sum|=a[i];18 int x=sum;19 for(rg int i=16;i;i--)if(x>=(1< =m) printf("%d\n",sum);22 else{23 for(rg int i=0;i<=n;i++)24 for(rg int j=0;j =k) ans=i;31 printf("%d\n",ans);32 }33 return 0;34 }