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;
}

猜你喜欢

转载自www.cnblogs.com/visualVK/p/9159883.html