zoukankan      html  css  js  c++  java
  • 背包搜索--LH

    题解:搜索 meet in the middle

    先搜一半,假设某个状态的体积是p,那么就要从另一半里找到体积小于

    等于v-p 价值最大的状态。二分+前缀和。

    代码:不会前缀和,暴力瞎写的。没有评测的地方..=^=

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    using namespace std;
    
    int an,bn,n,m,p,q,w[50],c[50];
    LL ans;
    struct WP{
        LL w,c;
        bool operator < (const WP &a) const{
          return w<a.w;
        }
    }wp[1050000];
    
    
    LL maxx(LL a,LL b){
        return a>=b?a:b;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d%d",&w[i],&c[i]);
        an=n/2;bn=n-an;
        for(int st=0;st<(1<<an);st++){
            p++;
            for(int i=0;i<an;i++){
                if((st>>i)&1){
                    wp[p].w+=w[i+1];
                    wp[p].c+=c[i+1];
                }
            }
        }
        sort(wp+1,wp+p+1);
        for(int st=0;st<(1<<bn);st++){
            WP all;all.w=0;all.c=0;//清为0 
            for(int i=0;i<bn;i++){
                if((st>>i)&1){
                    all.w+=w[n-i];
                    all.c+=c[n-i];
                }
            }
            WP gg;gg.w=m-all.w;gg.c=0;
            int cc=upper_bound(wp+1,wp+p+1,gg)-wp;
        //    cout<<all.w<<"  " <<gg.w<<"  "<<cc<<endl;
            for(int i=1;i<cc;i++)
                ans=maxx(ans,all.c+wp[i].c);
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    +1和*2
    线段树(区间最大值和最大值的个数)
    CodeForces
    莫队算法入门(暴力而不失优雅)
    二分迷宫
    全错排公式
    C++ PAT乙 1051. 复数乘法 (15)
    C++ PAT乙 1070. 结绳(25)
    C++ PAT乙 1080. MOOC期终成绩 (25)
    C++ PAT 1073. 多选题常见计分法(20)
  • 原文地址:https://www.cnblogs.com/zzyh/p/7642757.html
Copyright © 2011-2022 走看看