zoukankan      html  css  js  c++  java
  • 「HDU 5887」Herbs Gathering (背包)

    题意:原题在这

    给定背包容量和n个物品每个的价值和重量,求能装的物品的最大价值。(采药)

    附一组自己出的数据,虽然不够刁钻但是查错够用:

    5 100
    101 200
    99 1
    1 2
    98 20
    2 50

    做法:(详见行内注释)


    做法1:

    1. 因为dp解法的复杂度为O(V*N),w[i]和v[i]都在10e9,所以不能dp只能dfs

    2. 一种按体积排序的做法:

        按照体积由大到小排序,如果后面能取完的就直接取完;

        如果后面一直选择最优策略(能获得的最大价值加上已有的)都不好于现在的答案则break;

        (参考:https://blog.csdn.net/qq_21057881/article/details/52577874)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define maxn 105
    typedef long long ll;
    
    int n,k;
    long long sw[maxn],sv[maxn];
    struct node  
    {
        int w,v;
        double rate;//物品的性价比
    }pack[maxn];
    
    bool cmp(node x,node y) {return x.w>y.w;}
    
    long long ans=0;
    void dfs(int pos,int maxx,ll target)
    {
        if(pos==n)//尽量取完
        {
            if(maxx>=pack[pos].w)//如果能装下
                ans=max(ans,target+pack[pos].v);
            else//装不下
                ans=max(ans,target);
            return;
        }
        if(sw[pos]<=maxx)//还能装
        {
            ans=max(ans,target+sv[pos]);
            return;
        }
        if(target+sv[pos]<=ans) return;//要搜的+搜到的 都不好于现在,不搜
        dfs(pos+1,maxx,target);
        if(maxx>=pack[pos].w)
            dfs(pos+1,maxx-pack[pos].w,target+pack[pos].v);
    }
    
    int main()
    {
        while(scanf("%d%d",&n,&k)!=EOF)
        {
            ans=0; sw[n+1]=0; sv[n+1]=0;
            for(int i=1;i<=n;i++)
            {
                cin>>pack[i].w>>pack[i].v;
                pack[i].rate = 1.0*pack[i].v/pack[i].w;//计算性价比
            }
            sort(pack+1,pack+n+1,cmp);
            for(int i=n;i>=1;i--)
            {
                sv[i]=sv[i+1]+pack[i].v;
                sw[i]=sw[i+1]+pack[i].w;
            }
            dfs(1,k,0);
            cout<<ans<<endl;
        }
    }

    做法2:

    1. 先按性价比排序,直接把不能选的去掉,之后搜索的时候若剩下的背包空间都以最高性价比选时不会比已找到的最优解更好时则剪枝

    (参考:https://blog.csdn.net/consciousman/article/details/52572702)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define maxn 105
    #define INF 0x3f3f3f3f
    typedef long long LL;
    
    int n,k;
    long long cnt,ans;
    struct node  
    {
        long long w,v;
        double r;//物品的性价比
    }pack[maxn];
    
    bool cmp(node x,node y) {return x.r>y.r;}
    
    int check(int i,long long sw,long long sv)
    {
        for(int j=i; j<cnt && sw<k;j++)
        {
            if(pack[j].w+sw<=k)
            {
                sw+=pack[j].w;
                sv+=pack[j].v;
            }
            else
            {
                sv+=pack[j].r*(k-sw);
                sw=k;
            }
        }
        return sv>ans;
    }
    
    void dfs(int i,long long sw,long long sv)
    {
        ans=max(ans,sv);
        if(i<cnt && check(i,sw,sv))
        {
            if(sw+pack[i].w<=k)
                dfs(i+1,sw+pack[i].w,sv+pack[i].v);
            dfs(i+1,sw,sv);
        }
    }
    
    int main()
    {
        while(scanf("%d %d",&n,&k)!=EOF)
        {
            cnt=ans=0;
            for(int i=1;i<=n;i++)
            {
                long long w,v;
                cin>>w>>v;
                if(w<=k)
                {
                    pack[++cnt].w=w;
                    pack[cnt].v=v;
                    pack[cnt].r=(v+0.0)/w;
                    // pack[cnt++]=(node){w, v, (v+0.0)/w};
                }
            }
            sort(pack+1,pack+1+cnt,cmp);
            dfs(0,0,0);
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    深入Activity
    swift -变量的定义与使用
    tomcat中的Manager App帐号password管理
    TabLayout+Fragment+ViewPager+FragmentStatePagerAdapter实现Tab标签
    基于redis的分布式ID生成器
    Event-Souring模式
    Tensorflow
    RabbitMQ消息队列(五):Routing 消息路由
    RabbitMQ消息队列(四):分发到多Consumer(Publish/Subscribe)
    RabbitMQ消息队列(三):任务分发机制
  • 原文地址:https://www.cnblogs.com/LocaEtric/p/9275655.html
Copyright © 2011-2022 走看看