• POJ


    题意:求N个元素的非空子集和的绝对值最接近0,在此条件下子集大小尽量小,N≤35。

    N/2是17和18,217和218都是1e5的数量级,是可以枚举的。

    枚举后得到的集合记为P,Q,ans要么单独在P或者Q中,要么是两者的和。

    把Q中所有元素反号以后,枚举P中元素pi,就是找一个最接近pi的qj。

    所以只要排好序,值相同的保留集合最小的,然后维护两个单调的下标就好。(也可以二分

    m = n/2,复杂度为O(mlogm)

    POJ上编译abs比较奇怪,要自己写一个,不然CE

    /*********************************************************
    *            ------------------                          *
    *   author AbyssalFish                                   *
    **********************************************************/
    #include<cstdio>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    #include<cmath>
    #include<numeric>
    using namespace std;
    
    typedef long long ll;
    inline ll Abs(const ll &v){ return v<0?-v:v; }
    
    const int MAX_N = 35, half = 1<<17;
    ll a[MAX_N], b[MAX_N];
    int N;
    
    struct Dat
    {
        ll v; int c;
        Dat(){}
        Dat(ll v,int c):v(v),c(c){}
        bool operator < (const Dat& th) const {
            return Abs(v) < Abs(th.v) || (Abs(v) == Abs(th.v) && c < th.c);
        }
        Dat operator & (Dat &th){
            return Dat(v-th.v,c+th.c);
        }
    }p[half], q[half<<1];
    
    bool cmp (const Dat& ts, const Dat& th) {
        return ts.v < th.v || (ts.v == th.v && ts.c < th.c);
    }
    
    Dat ans;
    
    int prepare(ll *x, Dat *y, int k)
    {
        int s = 0;
        for(int S = (1<<k); --S; s++){
            y[s].v = y[s].c = 0;
            for(int i = 0; i < k; i++){
                if(S>>i&1){
                    y[s].c++;
                    y[s].v += x[i];
                }
            }
            ans = min(ans,y[s]);
        }
        sort(y,y+s,cmp);
        if(!s) return 0;
        k = 0;
        for(int i = 1; i < s; i++){
            if(y[i].v != y[k].v) {
                if(++k != i) y[k] = y[i];
            }
        }
        return k+1;
    }
    
    void solve()
    {
        int k = N>>1;
        for(int i = 0; i < k; i++) {
            scanf("%I64d",a+i);
        }
        for(int i = 0; i < N-k; i++) {
            scanf("%I64d",b+i);
            b[i] = -b[i];
        }
        ans.v = b[0]; ans.c = 1;
        int sz1 = prepare(a,p,k);
        //sort(p,q+sz1,cmp);
        int sz2 = prepare(b,q,N-k);
        for(int i = 0, j = 0; i < sz1; i++){
            while(j < sz2 && p[i].v > q[j].v) j++;
            if(j) ans = min(ans,p[i]&q[j-1]);
            if(j < sz2) ans = min(ans,p[i]&q[j]);
        }
        printf("%I64d %d
    ",Abs(ans.v), ans.c);
    }
    
    //#define LOCAL
    int main()
    {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif
        //cout<<half; 1e5
        while(scanf("%d",&N),N){
            solve();
        }
        return 0;
    }
  • 相关阅读:
    postgresql数据库
    运维平台cmdb配置库
    该微信用户未开启“公众号安全助手”的消息接收功能,请先开启后再绑定
    公众号开发:登录的微信号未绑定公众号的网页开发者
    在图片上指定区域写文字,超过长度自动换行
    Vue3基础知识提炼
    将博客搬至CSDN
    cglib应用
    mysql根据库表生成文档
    nginx 代理 ws协议
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4975710.html
Copyright © 2020-2023  润新知