• 2019牛客多校第⑨场D Knapsack Cryptosystem(折半搜索)


    原题:https://ac.nowcoder.com/acm/contest/889/D

    题意:

    给定大小为n(<=36)的集合a,整数s,求a的一个和为s的子集(有且只有一个)

    思路:

    直接搜索要(2^{36})次,时间过多,考虑一次搜索前半集合,一次搜索后半集合,得到两个(2^{16})的答案数组,就变成了双数组匹配问题

    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    using namespace std;
    typedef long long ll;
    const ll maxn=1e6+5;
    struct node{
        ll vis,v;//用二进制数vis表示元素的选择情况
        node(ll a=0,ll b=0):vis(a),v(b){}
        bool operator<(node b){
            return v<b.v;
        }
    }N[maxn];
    ll a[40];
    ll n,half,cnt;
    ll s;
    void dfs(ll cur,ll sum,ll vis){
        if(sum>s)return;
        if(cur==half){
            N[++cnt].vis=vis;
            N[cnt].v=sum;
            return;
        }
        if(a[cur]+sum<=s) dfs(cur+1,sum+a[cur],vis|1<<(cur-1));
        dfs(cur+1,sum,vis);
    }
    void dfs_(ll cur,ll sum,ll vis){
        if(sum>s) return;
        if(cur==n+1){
            ll temp=s-sum;
            ll p=lower_bound(N+1,N+1+cnt,node(1,temp) )-N;
            if(N[p].v==temp){
                ll t=N[p].vis;
                for(int i=1;i<half;i++){
                    if(t&1) printf("1");
                    else printf("0");
                    t=t>>1;
                }
                t=vis;
                for(int i=half;i<=n;i++){
                    if(t&1) printf("1");
                    else printf("0");
                    t=t>>1;
                }
                printf("
    ");
                exit(0);
            }
            return;
        }
        if(sum+a[cur]<=s) dfs_(cur+1,sum+a[cur],vis|1<<(cur-half));
        dfs_(cur+1,sum,vis);
    }
    int main(){
        cin>>n>>s;
        half=n/2;
        for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
        dfs(1,0,0);
        sort(N+1,N+1+cnt);
        dfs_(half,0,0);
    }
    
  • 相关阅读:
    数据库中随机返回n条数据的方法
    sql中NULL之恨
    数据库性能的查询优化特刊待续
    sql中exists替换in的区别
    代码的效率问题看一下代码
    检测数据库性能的方法
    Linux随堂1
    设置网页的图标
    C# 线程、timer例句
    转:1.2 Oracle表空间的操作
  • 原文地址:https://www.cnblogs.com/ucprer/p/11359864.html
Copyright © 2020-2023  润新知