1. 程式人生 > >hdu 4001解題報告

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;

}