zoukankan      html  css  js  c++  java
  • hihocoder 1496 寻找最大值(高维前缀最大次大值)

    【题目链接】 https://hihocoder.com/problemset/problem/1496

    【题目大意】

      给定N个数A1, A2, A3, ... AN,
      从中找到两个数Ai和Aj(i≠j)使得乘积Ai*Aj*(Ai&Aj)最大

    【题解】

      我们可以枚举x&y的结果z,找出两个数x&y==z使得x*y最大,更新答案即可,
      条件可以被削弱为z为x&y的子集,这种条件放缩不会导致最优解的丢失,
      z为x&y的子集等价于z为x的子集并且z为y的子集。
      那么我们只要找出以z为子集的最大值和次大值,然后枚举z即可计算出答案。
      复杂度O(k*2^k).

    【代码】

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    struct data{
        int val[2];
        data operator +(const data &rhs)const{
            int t_val[2]={val[0],val[1]};
            for(int i=0;i<2;i++){
                if(rhs.val[i]>t_val[0]){
                    t_val[1]=t_val[0];
                    t_val[0]=rhs.val[i];
                }else if(rhs.val[i]>t_val[1])t_val[1]=rhs.val[i];
            }return data{t_val[0],t_val[1]};
        }
    }dp[(1<<20)+10];
    int T,n;
    int main(){
        scanf("%d",&T);
        int all=1<<20;
        while(T--){
            for(int i=0;i<all;i++)dp[i]=data{0,0};
            scanf("%d",&n);
            for(int i=1,x;i<=n;i++){
                scanf("%d",&x);
                dp[x]=dp[x]+data{x,0};
            } 
            for(int i=0;i<20;i++)
                for(int j=0;j<all;j++)
                    if(~j&(1<<i))dp[j]=dp[j]+dp[j|(1<<i)];
            long long ans=0;
            for(int i=0;i<all;i++)ans=max(ans,1LL*i*dp[i].val[0]*dp[i].val[1]);
            printf("%lld
    ",ans);
        }return 0;
    }
  • 相关阅读:
    rzc generate exited with code -2147450730.
    c#WebService动态调用
    c#BarTender打印,打印微调
    记一次ios下h5页面图片显示问题
    FID
    RSA密钥对生成,并解析公钥指数和模数
    angularjs-6
    angularjs-5
    angularjs-4
    angularjs-4
  • 原文地址:https://www.cnblogs.com/forever97/p/hihocoder1496.html
Copyright © 2011-2022 走看看