POJ 2392 Space Elevator (DP)

题意:

有一头牛想要建一座石塔,他有很多不同类型的石块。
每类石块有三个属性:1. (h): 石块的高度;2. (a): 石块能达到的最大高度;3. (c): 石块的数量

思路:

采用多重背包。
注意点:在做背包前需要对石块能到达的最大高度(a)进行排序,防止石塔到了一定高度后,剩下的一些石块所能达到的最大高度小于这个高度,那剩下的这些石块也就不能往上放了。排序时按升序排序,先放能达到最大高度小的石块。

#include<cstdio>  
#include<cstring>  
#include<algorithm>  
using namespace std;  
struct node  
{  
    int h,a,c;  
}x[505];  
int dp[50005];  
int cmp(node a,node b)  
{  
    return a.a<b.a;//先按限制高度排序  
}  
int slove(int n)  
{  
    sort(x,x+n,cmp);  
    memset(dp,0,sizeof(dp));  
    int ans=0;  
    for(int i=0;i<n;++i)   
    {  
        for(int j=x[i].a;j>=x[i].h;--j)  
        {  
            int num=min(x[i].c,j/x[i].h);//最大可使用数量  
            for(int k=0;k<=num;++k)  
            {  
                int tp=dp[j-k*x[i].h]+k*x[i].h;  
                if(x[i].a>=tp)//高度条件控制  
                {  
                    dp[j]=max(tp,dp[j]);  
                }  
            }  
            ans=max(ans,dp[j]);  
        }  
    }  
    return ans;  
}  
int main()  
{  
    int n;   
    while(~scanf("%d",&n))  
    {  
        for(int i=0;i<n;++i)  
        {  
            scanf("%d%d%d",&x[i].h,&x[i].a,&x[i].c);  
        }  
        printf("%d\n",slove(n));  
    }  
    return 0;  
}
posted @ 2017-08-16 13:48  demianzhang  阅读(290)  评论(0编辑  收藏  举报