zoukankan      html  css  js  c++  java
  • POJ 2392 Space Elevator

    多重背包问题。


    我的背包训练第三题,多重背包。

    似乎有点理解多重背包了。


    我对背包九讲多重背包的理解:


    当某件物品 体积*数量 超过背包的容积的时候,这就做全然背包(相当于无限取)


    void completepack(int h,int cost,int a)
    {
        for(int i=cost;i<=a;i++)
            dp[i]=max(dp[i],dp[i-cost]+h);
    }

    而某件物品有多件却不能装满背包的时候,一件一件的来做01背包 太浪费。然后採取二进制的办法,每次乘2。


    把每次乘2 的 来做一次01 背包。

    这样时间复杂度减少 。



    void zeroonepack(int h,int cost,int a)
    {
        for(int i=a;i>=cost;i--)
            dp[i]=max(dp[i],dp[i-cost]+h);
    }


    这样分开然后再分解。让多重背包就简单起来了。

    void multiplepack(int h,int cost,int c,int a)
    {
        if(cost*c>=a)
        {
            completepack(h,cost,a);
            return;
            //相当于做一次全然背包
        }
        int k=1;
        while(k<c)
        {
            zeroonepack(h*k,cost*k,a);
            c-=k;
            k*=2;
            //多次01背包
        }
        zeroonepack(h*c,cost*c,a);
    }

    AC 代码:

    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<stack>
    #include<iostream>
    #include<list>
    #include<set>
    #include<cmath>
    #define INF 0x7fffffff
    #define eps 1e-6
    #define LL long long
    using namespace std;
    int dp[40001];
    int n;
    struct lx
    {
        int h,c,a;
    }l[401];
    bool cmp(lx a,lx b)
    {
        return a.a<b.a;
    }
    void zeroonepack(int h,int cost,int a)
    {
        for(int i=a;i>=cost;i--)
            dp[i]=max(dp[i],dp[i-cost]+h);
    }
    void completepack(int h,int cost,int a)
    {
        for(int i=cost;i<=a;i++)
            dp[i]=max(dp[i],dp[i-cost]+h);
    }
    void multiplepack(int h,int cost,int c,int a)
    {
        if(cost*c>=a)
        {
            completepack(h,cost,a);
            return;
        }
        int k=1;
        while(k<c)
        {
            zeroonepack(h*k,cost*k,a);
            c-=k;
            k*=2;
        }
        zeroonepack(h*c,cost*c,a);
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            int m=0;
            for(int i=0;i<n;i++)
            {
                scanf("%d%d%d",&l[i].h,&l[i].a,&l[i].c);
                m=max(m,l[i].a);
            }
            memset(dp,0,sizeof(dp));
            sort(l,l+n,cmp);
            for(int i=0;i<n;i++)
            {
                multiplepack(l[i].h,l[i].h,l[i].c,l[i].a);
            }
            int ans=0;
            for(int i=0;i<=m;i++)
                //printf("%d =
    ",dp[i]);
                ans=max(ans,dp[i]);
            printf("%d
    ",ans);
    
        }
    }
    




  • 相关阅读:
    Delphi中使用IdHTTP访问基于SSL协议(https)的网站
    一篇就算若干年后一看到仍会打动我的心的文章
    最全面的DBGrid点击标题实现排序
    最全面的DBGrid点击标题实现排序
    Delphi 2009(Tiburon)终于快要发布了
    C++树的实现
    linux常用命令
    Centos ulimit设置
    how tomcat works(第六章)
    how tomcat works(第五章)
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5061242.html
Copyright © 2011-2022 走看看