• Codevs 2144 砝码称重 2


    2144 砝码称重 2

     

     时间限制: 1 s
     空间限制: 16000 KB
     题目等级 : 钻石 Diamond
     
     
     
    题目描述 Description

    有n个砝码,现在要称一个质量为m的物体,请问最少需要挑出几个砝码来称?

    注意一个砝码最多只能挑一次

    输入描述 Input Description

    第一行两个整数n和m,接下来n行每行一个整数表示每个砝码的重量。

    输出描述 Output Description

    输出选择的砝码的总数k,你的程序必须使得k尽量的小。

    样例输入 Sample Input

    3 10
    5
    9
    1

    样例输出 Sample Output

    2

    数据范围及提示 Data Size & Hint

    1<=n<=30,1<=m<=2^31,1<=每个砝码的质量<=2^30

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define maxn 31
    int n,ans=0x7fffffff;
    long long a[maxn],s[maxn],m;
    bool cmp(int x,int y){return x>y;}
    long long qread(){
        long long i=0;
        char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch<='9'&&ch>='0'){i=i*10+ch-'0';ch=getchar();}
        return i;
    }
    void dfs(int pos,int cnt,long long sum){
        if(sum==m){ans=min(ans,cnt);return;}
        if(cnt>=ans)return;
        if(pos>n)return;
        for(int i=pos;i<=n;i++){
            if(s[i]<m-sum)return;
            if(a[i]>m-sum)continue;
            dfs(i+1,cnt+1,sum+a[i]);
        }
    }
    int main(){
        freopen("Cola.txt","r",stdin);
        scanf("%d",&n);
        m=qread();
        for(int i=1;i<=n;i++)a[i]=qread();
        sort(a+1,a+n+1,cmp);
        for(int i=n;i>=1;i--)s[i]=s[i+1]+a[i];
        dfs(1,0,0);
        printf("%d",ans);
    }
    100分 后缀和+剪枝
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<map> 
    using namespace std;
    int ans(1000),w[50],n;
    long long mm;
    map<int, int>m;
    void dfs(int js,int last,int sum,bool k)
    {
        int r=n;
        if(k){m[sum]=js;r/=2;}
        else
        {
            if(m.find(mm - sum)!=m.end())
            ans=min(ans,js+m[mm-sum]);
        }
        for(int i=last;i<r;i++)
        dfs(js+1,i+1,sum+w[i],k);
    }
    int main()
    {
        scanf("%d%lld",&n,&mm);
        for(int i=0;i<n;i++)
        scanf("%d",&w[i]);
        dfs(0,0,0,true);
        dfs(0,n/2,0,false);
        printf("%d
    ",ans);
        return 0;
    }
    100分 meet in the middle
  • 相关阅读:
    软件工程个人作业01
    阅读计划及浅读问题
    引言作业1
    多态和异常分析课后
    大道至简七八章阅读
    接口与继承 课后实践
    构建执法阅读笔记02
    冲刺第五天
    学习进度条七
    冲刺第四天
  • 原文地址:https://www.cnblogs.com/thmyl/p/7689087.html
Copyright © 2020-2023  润新知