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);
    
        }
    }
    




  • 相关阅读:
    终端操作各插件安装配置
    浅谈CSRF攻击方式
    教你突破基于HTTP_REFERER的防盗链的方法
    HTTP Referer简介
    如何利用百度蜘蛛referer找到报错页面入口?
    Flex 布局教程:语法
    HTTP 状态码
    RESTful API 设计最佳实践
    Javascript原型和原型链
    JS判断是什么设备是什么浏览器-主要用移动页面开发
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5061242.html
Copyright © 2011-2022 走看看