poj2392(多重背包,注意细节)

来源:互联网 发布:淘宝购物券在哪里设置 编辑:程序博客网 时间:2024/05/17 03:45

地址:http://poj.org/problem?id=2392

Space Elevator
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 7534 Accepted: 3542

Description

The cows are going to space! They plan to achieve orbit by building a sort of space elevator: a giant tower of blocks. They have K (1 <= K <= 400) different types of blocks with which to build the tower. Each block of type i has height h_i (1 <= h_i <= 100) and is available in quantity c_i (1 <= c_i <= 10). Due to possible damage caused by cosmic rays, no part of a block of type i can exceed a maximum altitude a_i (1 <= a_i <= 40000). 

Help the cows build the tallest space elevator possible by stacking blocks on top of each other according to the rules.

Input

* Line 1: A single integer, K 

* Lines 2..K+1: Each line contains three space-separated integers: h_i, a_i, and c_i. Line i+1 describes block type i.

Output

* Line 1: A single integer H, the maximum height of a tower that can be built

Sample Input

37 40 35 23 82 52 6

Sample Output

48

Hint

OUTPUT DETAILS: 

From the bottom: 3 blocks of type 2, below 3 of type 1, below 6 of type 3. Stacking 4 blocks of type 2 and 3 of type 1 is not legal, since the top of the last type 1 block would exceed height 40.

题意:要建一座太空电梯,由于宇宙射线的原因,每种材料均有最大可建高度。先给出每种材料的长度h_i、最大可建高度a_i和数量c_i,求电梯最大高度。

思路:根据材料最大可建高度来排一下序,然后在用多重背包。需要注意的是输出0的情况。

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct node{    int val,vol,num;}cas[410];int dp[40010],path[40010];bool kmp(node a,node b){    return a.vol<b.vol;}int main(){    int n,v,i,j;    while(scanf("%d",&n)>0)    {        //if(n==0) {puts("0");continue;}        memset(dp,0,sizeof(dp));v=0;        for(i=0;i<n;i++)            scanf("%d%d%d",&cas[i].val,&cas[i].vol,&cas[i].num);        sort(cas,cas+n,kmp);        for(i=0;i<n;i++)        {            memset(path,0,sizeof(path));            for(j=cas[i].val;j<=cas[i].vol;j++)            {                if((j==cas[i].val||dp[j-cas[i].val]!=0)&&dp[j-cas[i].val]+cas[i].val>dp[j]&&path[j-cas[i].val]+1<=cas[i].num)                {                    dp[j]=dp[j-cas[i].val]+cas[i].val;                    path[j]=path[j-cas[i].val]+1;                }            }        }        i=cas[n-1].vol;        while(!dp[i]&&i) i--;  //注意输出0的情况,所以这里的判断条件是!dp[i]&&i        printf("%d\n",i);    }}


原创粉丝点击