hdu 4001解題報告
-hdu- 4001 解題報告
題目大意:有n塊大小、高度不一的矩形磚塊,且型別為0,1,2三種,分別有不同疊放順序。求最終能夠得到的最大高度。
題目解析:dp動態規劃的型別,但先要進行對磚塊按長度、寬度和高度排序。接下去就是分三種情況進行dp,狀態dp[i]表示的是第i塊磚塊放置的位置的高度。
狀態轉移方程是dp[i]=max(dp[i],dp[j]+block[i].height),意思就是嘗試是否第i塊磚塊放在第j塊上後dp值會變大。
實現程式碼:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
typedef long long int64;
struct node{
longlong a, b, c, d;
}; //分別是長度,寬度,高度和型別
node l[1005]; //存放矩形資訊的陣列
int64 dp[1005]; //動態陣列,dp【i】表示第i塊磚塊位置的高度
int64 temp, ans; //ans 是最終的答案
int n;
bool cmp(node l, node r){ //多條件排序,長度從小到大,其次寬度從小到大,最次高度從大到小
if(l.a!= r.a) return l.a < r.a;
if(l.b!= r.b) return l.b < r.b;
returnl.d > r.d;
}
void dpfun(){ //dp函式主體
for(inti = 0; i < n; i ++ ) dp[i] = l[i].c; //各自放在最底層的時候
ans= l[0].c;
for(inti = 0; i < n; i ++ ){
if(l[i].d== 0){
for(intj = 0; j < i; j ++ ){
if(l[i].a>= l[j].a && l[i].b >= l[j].b && dp[j]+l[i].c > dp[i])
dp[i]= dp[j]+l[i].c; //如果滿足if的條件,則第i塊放在第j塊的上面
}
}elseif( l[i].d == 1 ){
for(intj = 0; j < i; j ++ ){
if(l[i].a>= l[j].a && l[i].b >= l[j].b && (l[i].a*l[i].b >l[j].a*l[j].b) && dp[j]+l[i].c > dp[i])
dp[i]= dp[j]+l[i].c;
}
}elseif(l[i].d == 2 ){
for(intj = 0; j < i; j ++ ){
if(l[i].a> l[j].a && l[i].b > l[j].b && dp[j]+l[i].c > dp[i])
dp[i]= dp[j]+l[i].c;
}
}
if(ans< dp[i]) ans = dp[i]; //列舉得到整個dp過程中出現過的最大的高度值
}
}
int main(){
inti, j, a, b, c, d;
while(scanf("%d", &n) != EOF ){
if(n == 0 ) break;
for(i = 0; i < n; i ++ ){
scanf("%d%d%d%d",&l[i].a, &l[i].b, &l[i].c, &l[i].d);
if(l[i].a < l[i].b ){ //預設a是長度,大於等於寬度b
temp= l[i].a;
l[i].a= l[i].b;
l[i].b= temp;
}
}
sort(l,l+n, cmp);
dpfun();
printf("%I64d\n",ans);
}
return0;
}