POJ - 2392 Space Elevator

题目大意:
有k种积木,每种有c_i个,每个积木所处的高度不能大于a_i,每个积木高为h_i,问应该如何搭积木,使积木高度 最高
分析:
多重部分和。《挑战程序设计》P63里有方法的详细解释,我就只做简单的分析了。dp[i][j]定义成用前i个积木搭 到j高度时,第i种积木剩下的数目,如果dp[i-1][j]>=0说明前i-1就可以搭到j高度,所以dp[i][j]=m[i].num;如 果j<m[i].h||dp[i-1][h-m[i].h]则说明用前i-1个无法拼到h-m[i].h;其他的情况都是 dp[i][j]=d[i-1][j-m[i].h]-1;而这种我们是可以直接用一维数组直接重复使用的(详细看代码)
code:
#define debug
#include<stdio.h>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<functional>
#include<iomanip>
#include<map>
#include<set>
#define pb push_back
#define dbg(x) cout<<#x<<" = "<<(x)<<endl;
#define lson l,m,rt<<1
#define cmm(x) cout<<"("<<(x)<<")";
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
const int maxn=1e5;
const int INF=0x3f3f3f3f;
const ll inf=0x7fffff;
const int mod=1e9+7;
const int MOD=10007;
//----
//define
int dp[40005];
struct node{
int h,mh,num;
node(int h=0,int mh=0,int num=0):h(h),mh(mh),num(num){}
bool operator <(const node &a)const{
return mh<a.mh;
}
}m[405];
//solve
void solve() {
int k;
cin>>k;
for(int i=1;i<=k;i++){
int h,mh,num;
cin>>h>>mh>>num;
m[i]=node(h,mh,num);
}
sort(m+1,m+1+k);
memset(dp,-1,sizeof(dp));
dp[0]=0;
int ans=0;
for(int i=1;i<=k;i++){
for(int j=0;j<=m[i].mh;j++){
if(dp[j]>=0)dp[j]=m[i].num;
else if(j<m[i].h||dp[j-m[i].h]<=0)dp[j]=-1;
else dp[j]=dp[j-m[i].h]-1;
}
}
for(int i=1;i<=m[k].mh;i++)if(dp[i]>=0)ans=i;
cout<<ans<<endl;
}
int main() {
ios_base::sync_with_stdio(0);
#ifdef debug
freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
cin.tie(0);
cout.tie(0);
solve();
return 0;
}

浙公网安备 33010602011771号