poj2392 space elevator

题目链接:https://vjudge.net/problem/POJ-2392

贪心的想,先堆限高低的木块,再堆限高更高的木块的方案是更优的,因为反之有可能限高低的木块无法堆.于是将木块按限高排序,然后做多重背包。有两个小优化:

1)如果当前的dp[j]=1,说明当前高度j已经可以由之前的木块堆出,直接continue;

2)如果再循环k(k=1~w[i].c)的时候,发现存在dp[j-k*w[i].h]=1,直接更新dp[j]=1后break,因为当前的高度已经可以被堆出

#include<cstring>
using namespace std;

const int maxw=40000+10;
const int maxn=400+10;
struct node{
    int h,a,c;
};
node w[maxn];
int dp[maxw];
int n,i,j,k,t,ans,m;

bool cmp(node p,node q){
    if (p.a==q.a) return (p.h<q.h);
    else return (p.a<q.a);
} 

int main(){
    //freopen("poj2392.txt","r",stdin);
    cin>>n;
    for (i=1;i<=n;i++) cin>>w[i].h>>w[i].a>>w[i].c;
    sort(w+1,w+n+1,cmp);
    memset(dp,0,sizeof(dp));
    dp[0]=1;
    for (i=1;i<=n;i++){
      for (j=w[i].a;j>=0;j--) {
          if (dp[j]) continue;
          for (k=1;k<=w[i].c;k++)
            if (j>=k*w[i].h)
              if (dp[j-k*w[i].h]){
                  dp[j]=1;break;
              }
        }
    }
    for (ans=40000;ans>=0;ans--) if (dp[ans]) break;
    cout<<ans<<endl;
    //fclose(stdin);
    return 0;
}
poj2392

猜你喜欢

转载自www.cnblogs.com/edmunds/p/12783660.html