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