您的位置:首页 > 其它

poj 2392 Space Elevator 背包

2013-04-14 19:38 288 查看
这个题目本质上是一个多重背包

但是有一个限制条件,就是每个物品堆放的高度都有一个最大值,不能超过

刚开始被这个条件吓到了,考虑到用搜索的做法,但是400件物品,搜索无法承受

就又回到dp上面,其实贪心的思想就可以保证最优,那些堆放高度限制低的物品一定是放在底下的

所以先按堆放高度限制升序排序,然后就可以上多重背包了

多重背包的解法:用二进制的思想来拆分物品,使之转化成01背包

#include

#include

#include

using namespace std;

int a[4001][2],lon=0;

int ans[400001];

int max(int a,int b)

{

if(a>b)
return(a);

return(b);

}

int min(int a,int b)

{

if(a

return(b);

}


int main()

{

int k;

scanf("%d",&k);

for(int
i=1;i<=k;i++)

{

int h,l,c;

scanf("%d %d %d",&h,&l,&c);

int tmp=1;

while(tmp<=c)

{

c-=tmp;

a[++lon][0]=tmp*h;

a[lon][1]=l;

tmp*=2;

}

if(c)

{

a[++lon][0]=c*h;

a[lon][1]=l;

}

}

// for(int
i=1;i<=lon;i++)

// printf("%d
%d\n",a[i][0],a[i][1]);

for(int i=1;i<=lon;i++)

for(int j=lon;j>=i+1;j--)

if(a[j][1]

{

int tmp=a[j-1][0];

a[j-1][0]=a[j][0];

a[j][0]=tmp;

tmp=a[j-1][1];

a[j-1][1]=a[j][1];

a[j][1]=tmp;

}

memset(ans,0,sizeof(ans));

ans[0]=1;

int
lonh=0;

for(int
i=1;i<=lon;i++)

{

for(int j=min(lonh,a[i][1]-a[i][0]);j>=0;j--)

if(ans[j])

{

//
printf("%d %d\n",j+a[i][0],a[i][0]);

ans[j+a[i][0]]=1;

lonh=max(j+a[i][0],lonh);

}

}

for(int
i=400001;i>=0;i--)

if(ans[i])

{

printf("%d\n",i);

break;

}

return
0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: