• ZOJ--3631--Watashi's BG【枚举】


    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4777

    题意:有n天,告诉你每天的花费,别人给你一笔资金m,你自己也有一部分资金(能够如果花不完),每天仅仅能花自己的钱或者花资金m中的钱,不能混着花,问m最多能花多少?


    思路:考虑到数据比較小,n最多仅仅有30,能够用枚举来做,枚举每天花m或者不花m,二进制枚举,复杂度2^30。这样复杂度要超时的,土豪说能够分两部分枚举,把结果存入两个数组,然后这两个数组结果再合并,复杂度n^2,这样二进制枚举最多是两个2^15,大大缩短了时间复杂度。

    后来我又用dfs写了一遍,果断T,看了别人的代码,有个剪枝非常关键,当前已使用的资金与全部还未使用的资金相加假设小于等于已得到的最大值,则剪枝。


    二进制枚举代码

    #include<cstring>
    #include<string>
    #include<fstream>
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<set>
    #include<vector>
    #include<stack>
    #include<ctime>
    #include<cstdlib>
    #include<functional>
    #include<cmath>
    using namespace std;
    #define PI acos(-1.0)
    #define MAXN 5000100
    #define eps 1e-7
    #define INF 0x7FFFFFFF
    #define LLINF 0x7FFFFFFFFFFFFFFF
    #define seed 131
    #define MOD 1000000007
    #define ll long long
    #define ull unsigned ll
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    
    int a[200010],b[200010],va[40],vb[40];
    int main(){
        int i,j;
        int n,m;
        int la,lb,cnta,cntb,ans;
        while(scanf("%d%d",&n,&m)!=EOF){
            la = lb = cnta = cntb = ans = 0;
            for(i=0;i<n/2;i++){
                scanf("%d",&va[i]);
                la++;
            }
            for(i=n/2;i<n;i++){
                scanf("%d",&vb[i-n/2]);
                lb++;
            }
            int l = (1<<la);
            for(i=0;i<l;i++){
                int sum = 0;
                for(j=0;j<la;j++){
                    if(i&(1<<j)){
                        sum += va[j];
                    }
                }
                if(sum<=m){
                    a[cnta++] = sum;
                    ans = max(sum,ans);
                }
            }
            l = (1<<lb);
            for(i=0;i<l;i++){
                int sum = 0;
                for(j=0;j<lb;j++){
                    if(i&(1<<j)){
                        sum += vb[j];
                    }
                }
                if(sum<=m){
                    b[cntb++] = sum;
                    ans = max(sum,ans);
                }
            }
            sort(a,a+cnta);
            sort(b,b+cntb);
            if(ans==m){
                printf("%d
    ",ans);
                continue;
            }
            for(i=cnta-1;i>=0;i--){
                for(j=cntb-1;j>=0;j--){
                    if(a[i]+b[j]<=m){
                        ans = max(ans,a[i]+b[j]);
                        break;
                    }
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }


    DFS代码

    #include<cstring>
    #include<string>
    #include<fstream>
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<set>
    #include<vector>
    #include<stack>
    #include<ctime>
    #include<cstdlib>
    #include<functional>
    #include<cmath>
    using namespace std;
    #define PI acos(-1.0)
    #define MAXN 5000100
    #define eps 1e-7
    #define INF 0x7FFFFFFF
    #define LLINF 0x7FFFFFFFFFFFFFFF
    #define seed 131
    #define MOD 1000000007
    #define ll long long
    #define ull unsigned ll
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    
    int a[40],jz[40];
    int n,m,maxm;
    void dfs(int step,int cnt){
        if(cnt>m)   return ;
        maxm = max(maxm,cnt);
        if(step<1) return ;
        if(cnt+jz[step]<=maxm)  return ;    //防TLE剪枝
        dfs(step-1,cnt);
        dfs(step-1,cnt+a[step]);
    }
    int main(){
        int i,j;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            jz[0] = 0;
            for(i=1;i<=n;i++)    jz[i] = jz[i-1] + a[i];
            maxm = 0;
            dfs(n,0);
            printf("%d
    ",maxm);
        }
        return 0;
    }
    
    


  • 相关阅读:
    网络编程
    WPF DataGrid点击有效区域Check
    WPF DataGrid显示表格中编辑Check数据
    WPF DataGrid显示按上下键移动数据、多个CheckBox勾选
    Python 下载小说到本地
    WPF 条件不等于时触发改变颜色
    WPF 反射 排序 、启动定时器等
    # WPF DataGrid文本编辑验证
    Nginx 与 X-Forwarded-For
    如何正确设置nginx中remote_addr和x_forwarded_for参数
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/3979731.html
Copyright © 2020-2023  润新知