题目链接:http://poj.org/problem?id=2392
题意:有K种规格的楼梯,现在要用这K种规格的楼梯架高(就是一个楼梯一个接起来,变成一个更高的楼梯),但其中每种规格的楼梯有个限制,就是它的高度不能超过a(连接上它后楼梯的总高度不能超过a).现在告诉你这K种楼梯每种楼梯的高度为h,限制为a,有c个。问用这些楼梯最高能拼接成多高的楼梯。
首先要将这K种楼梯按限制a从小到大排序(不能清除解释,只好理解成常识了,莫见怪,呵呵。。),然后按照多重背包处理就Ok了。
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Node{
int h;
int a;
int c;
}node[410];
int K,ans;
int dp[40005];
int min(int a,int b)
{
return a<b ? a : b;
}
int max(int a,int b)
{
return a>b ? a : b;
}
int cmp(const void *x,const void *y)
{
return (*(struct Node *)x).a-(*(struct Node *)y).a;
}
void ZeroOnePack(int cost,int V)
{
int v;
for(v=V;v>=cost;v--)
{
dp[v]=max(dp[v],dp[v-cost]+cost);
}
}
void MultiplePack(int id,int amount)
{
int k=1;
while(k<amount)
{
ZeroOnePack(k*node[id].h,node[id].a);
amount -= k;
k *= 2;
}
ZeroOnePack(amount*node[id].h,node[id].a);
}
int main()
{
int i;
int minnum;
while(scanf("%d",&K)!=EOF)
{
for(i=0;i<K;i++)
scanf("%d%d%d",&node[i].h,&node[i].a,&node[i].c);
qsort(node,K,sizeof(struct Node),cmp);
memset(dp,0,sizeof(dp));
for(i=0;i<K;i++)
{
minnum=min(node[i].c,node[i].a/node[i].h);
MultiplePack(i,minnum);
}
ans =0;
for(i=0;i<=node[K-1].a;i++)
if(dp[i]>ans)
ans = dp[i];
printf("%d\n",ans);
}
return 0;
}