poj 2392 Space Elevator(多重背包)

来源:互联网 发布:天刀捏脸数据保存在哪 编辑:程序博客网 时间:2024/05/16 17:04

题意:

k种石头(不用在意具体是什么东西),每种石头的高度为h,这种石头不能处于超过a的高度,数量为c,问最多能用这些石头叠出多大的高度


解题思路:

这是一道稍微有点改动的多重背包题目,被改为每种石头都有一个容量限制。

多重背包的问题我们可以进行转换,对于c*h>=a的石头,在不超过a的条件下,无论去多少块石头都不会用完c,所以就是可以转换为完全背包问题,

而c*h<a的石头,就是c个(价值为h,2*h,....c*h)的01背包问题了,这里可以用二进制加速一下。因为有转换成二进制数后能表示出1到c的所有数,所以效果一样。


代码:


#include <iostream>#include <cstdio>#include <algorithm>using namespace std;const int maxn=40000;struct p{    int a;    int h;    int c;}x[505];bool cmp(p a, p b){    return a.a<b.a;}int f[maxn+5];void complete(int x, int y){    int i;    for(i=x; i<=y; i++)    {        if(f[i-x])f[i]=1;    }    return;}void ZeroPack(int x, int y, int z){    for(int i=z; i>=x; i--)    {        if(f[i-x])        {           f[i]=1;         }    }    return;}int main(){    int k;    cin>>k;    int i, j;    for(i=0; i<k; i++)    {        scanf("%d%d%d", &x[i].h, &x[i].a, &x[i].c);    }    sort(x, x+k, cmp);    f[0]=1;    for(i=0; i<k; i++)    {        if(x[i].c*x[i].h>=x[i].a)        {            complete(x[i].h, x[i].a);        }        else         {            int e=1;            for(j=x[i].c; j>e; )            {                ZeroPack(e*x[i].h, e, x[i].a);               j-=e;               e<<=1;            }                ZeroPack(j*x[i].h, j, x[i].a);        }    }        for(j=maxn; j>0; j--)    {        if(f[j])break;    } //   for(; j>0; j--)printf("%d\n", f[j]);    printf("%d\n", j);}


0 0
原创粉丝点击