• BZOJ 4976 [Lydsy1708月赛]宝石镶嵌


    【题解】

      我们设总共有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 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     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<<i)) m++,x-=(1<<i);
    20     if(n-k>=m) printf("%d
    ",sum);
    21     else{
    22         for(rg int i=0;i<=n;i++)
    23             for(rg int j=0;j<N;j++) f[i][j]=n;
    24         f[0][0]=0;
    25         for(rg int i=1;i<=n;i++) {
    26             for(rg int j=0;j<N;j++)
    27             f[i][j|a[i]]=min(f[i][j|a[i]],f[i-1][j]+1); 
    28             for (rg int j=0;j<N;j++)
    29             f[i][j]=min(f[i][j],f[i-1][j]);
    30         }
    31         for(rg int i=0;i<N;i++) if(f[n][i]<=n-k) ans=i;
    32         printf("%d
    ",ans);
    33     }
    34     return 0;
    35 }
    View Code
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     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<<i)) m++,x-=(1<<i);
    20 //    printf("%d %d
    ",m,sum);
    21     if(n-k>=m) printf("%d
    ",sum);
    22     else{
    23         for(rg int i=0;i<=n;i++)
    24             for(rg int j=0;j<N;j++) f[i][j]=-n;
    25         f[0][0]=0;
    26         for(rg int i=1;i<=n;i++)
    27             for(rg int j=0;j<N;j++)
    28                 f[i][j]=max(f[i][j],f[i-1][j]+1),
    29                 f[i][j|a[i]]=max(f[i][j|a[i]],f[i-1][j]);
    30         for(rg int i=1;i<N;i++) if(f[n][i]>=k) ans=i;
    31         printf("%d
    ",ans);
    32     }
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    day3-python之函数进阶(三)
    day3-python之函数初识(二)
    day3-python之文件操作(一)
    tomcat
    集群
    nginx
    nginx--zabbix监控status waiting
    zabbix监控之mysql主从状态&mysql主从延迟
    zabbix监控之进程&日志监控
    zabbix监控流程(监控linux上某个文件是否有改动)
  • 原文地址:https://www.cnblogs.com/DriverLao/p/9761427.html
Copyright © 2020-2023  润新知