• 51Nod3049 挑选数字


    Problem

    给出n个正整数,从中挑选若干个,使得他们的和为m。如果存在多个,输出排序后字典序最小的一组。如果没有找到任何一组,输出"No Solution"。

    Solution

    如果n大于15,从16开始分成两部分,先枚举后一半可能出现的值,map记录,然后按顺序枚举前一半,如果能和某个值组成m就记录每个数,返回,再枚举后一半,找到具体的数字。

    主要是dfs写的太烂了,交对看别人的才知道怎么写。

    Code

    #include<stdio.h>
    #include<set>
    #include<iostream>
    #include<stack>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<queue>
    #include<algorithm>
    typedef long long ll;
    typedef long double ld;
    typedef double db;
    #define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    using namespace std;
    const int mod=1e9+7;
    inline int mo(ll a,int p){
        return a>=p?a%p:a;
    }
    inline int rd() {
        int x = 0, f = 1;
        char ch;
        while (ch < '0' || ch > '9') {
            if (ch == '-')f = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return f * x;
    }
    inline ll gcd(ll x, ll y){
        return y==0?x:gcd(y,x%y);
    }
    inline ll speed(ll a,ll b){
        ll cur=a,anss=1;
        while(b){
            if(b&1) anss=anss*cur;
            cur=cur*cur;
            b>>=1;
        }
        return anss;
    }
    const int MAXN=1e5;
    bool ipr[MAXN+20];
    int cnt,pri[MAXN/5];
    void prime(){//埃式筛法
        int N=sqrt(MAXN)+0.5,mul;
        memset(ipr,true,sizeof(ipr));
        ipr[1]=false;
        for(int i=2;i<=N;i++){
            if(ipr[i]==true){
                i==2?mul=1:mul=2;
                for(int j=i*i;j<=MAXN;j+=i*mul){
                    ipr[j]=false;
                }
            }
        }
        for(int i=2;i<=MAXN;i++){
            if(ipr[i]==true){
                pri[++cnt]=i;
            }
        }
    }
    int n,m;
    int a[50];
    int ans[50],ct=0,al=0,mid;
    bool fg=false;
    map<int,int>mp;
    int sss=15;
    void dfs(int cur,int sum,int cou){
        if(fg) return;
        if(sum==m){
            fg=true;
            ct=cou;
            return;
        }
        if(cur==n+1) return;
        ans[cou+1]=a[cur];
        if(sum+a[cur]<=m&&al-sum-a[cur]>=m-sum-a[cur]) dfs(cur+1,sum+a[cur],cou+1);
    
        if(al-sum>=m-sum) dfs(cur+1,sum,cou);
    
    }
    void dfs1(int cur,int sum){
        mp[sum]=1;
        if(cur==n+1) return;
        dfs1(cur+1,sum+a[cur]);
        dfs1(cur+1,sum);
    }
    void dfs2(int cur,int sum,int cou){
        if(fg) return;
        if(mp[m-sum]){
            fg=true;
            mid=sum;
            ct=cou;
            return;
        }
        if(cur==sss+1) return;
        ans[cou+1]=a[cur];
        if(sum+a[cur]<=m&&al-sum-a[cur]>=m-sum-a[cur]) dfs2(cur+1,sum+a[cur],cou+1);
    
        if(al-sum>=m-sum) dfs2(cur+1,sum,cou);
    
    }
    bool fg2=false;
    void dfs3(int cur,int sum,int cou){
        if(fg2) return;
        if(sum==m){
            fg2=true;
            ct=cou;
            return;
        }
        if(cur==n+1) return;
        ans[cou+1]=a[cur];
        if(sum+a[cur]<=m&&al-sum-a[cur]>=m-sum-a[cur]) dfs3(cur+1,sum+a[cur],cou+1);
        if(al-sum>=m-sum) dfs3(cur+1,sum,cou);
    
    }
    int main(){
        //io_opt;
    
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            al+=a[i];
        }
        if(al<m){
            printf("No Solution
    ");
            return 0;
        }
        sort(a+1,a+1+n);
        if(n<=sss){
            dfs(1,0,0);
        }
        else{
            dfs1(sss+1,0);
            dfs2(1,0,0);
            //cout<<ct<<endl;
            if(fg) dfs3(sss+1,mid,ct);
            //cout<<ct<<endl;
        }
    
    
        if(fg){
            for(int i=1;i<=ct;i++){
                printf("%d ",ans[i]);
            }
            printf("
    ");
        }
        else{
            printf("No Solution
    ");
        }
        return 0;
    }
    
    
  • 相关阅读:
    java执行shell命令,chmod 777 xxx,改变权限无效的解决办法。
    SpringBoot配置双数据源(一个项目同时连接操作两台数据库)
    《机器学习》周志华西瓜书习题参考答案:第2章
    《机器学习》周志华西瓜书学习笔记(二):模型评估与选择
    只用一套解决方案,就可解决80%的交通物流行业信息难题
    原码、反码、补码
    400+节点的Elasticsearch集群运维
    史上最全PostgreSQL体系结构
    IDEA创建JAVAFX并打包成exe
    DB2 Zos 浅谈
  • 原文地址:https://www.cnblogs.com/sz-wcc/p/13188013.html
Copyright © 2020-2023  润新知