做了一道zoj上的題目,發現是一道經典原題的改編(只改了題目背景。。資料都一樣)。
zoj problem set - 1093 解題報告
題目分類:動態規劃
題目大意:有n種木塊,每種都是無限提供,木塊可以隨意擺放(即每條邊都可能為高)。當某一塊木塊的長和寬都小於下面的木塊時,才能疊在上面。要求最高能疊多高。
恰好在做這一題的時候,看了看書,發現了一道例題跟這題一模一樣——巴比倫塔。所以我把題目原型擺出來。
巴比倫塔(the tower of babylon,uva 437)
有n(n≤30)種立方體,每種有無窮多個。要求選一些立方體摞成一根盡量高的柱子(可以自行選擇哪一條邊作為高),使得每個立方體的底面長寬分別嚴格小於它下方立方體的底面長寬。
每個人有每個人的寫法,或許有比我的**更簡潔的,不過我只講我的思路,我覺得簡單易懂的。
每一種木塊都有三種擺放方式,因為有三條邊。用b[n][3]來儲存輸入的每個木塊的長寬高,再用a[n*3][3]儲存所有的情況。剛開始我想先排序然後判斷可以疊加就一直往上加,然後發現答案是錯的。這樣是貪心,但不能用貪心,因為每選一種木塊都會影響到後面的所有木塊。我們要分析問題的狀態。在這3*n種情況中,我們用d[i]來表示以第 i 塊木塊為頂層的最大高度。因為能放在第 i 塊木塊下方的情況可能不止一種,當然也可能沒有,所以我又用了乙個put[i][j]表示第 i 塊木塊能否放在第 j 塊木塊上。於是 d[i] = max 。這樣就得到了狀態轉移方程。其實每次做動態規劃的關鍵就是幾點:1、狀態和狀態轉移方程。2、做記錄。 做記錄就是我們這裡的d[i],這樣每個方案只會計算一次,不會重複計算,這才體現了動態規劃的優點。最終我的所求的最大高度 maxheight = max 。
把樣例測試過了之後就一遍ac了。**如下:
1 #include 2 #include 3 #include 4using
namespace
std;56
int a[91][3]; //
所有木塊可能
7int put[91][91]; //
put[i][j]表示i能放在j上
8int d[91]; //
d[i]表示以第i個木塊為頂層的最大高度
9int
n;10
int dp(int i) //
以第i塊木板為頂的最大高度
1122}23
return
ans;24}
25void output(int
times)
2636}37
}38for(i=0;i<3*n;i++)
3943 cout<<"
case
"<"
: maximum height =
"45int
main()
4665
//cout<<"可能情況:"<66
//for(i=0;i<3*n;i++)
67//
cout<<"i="<68 memset(d,0,sizeof
(d));
69 memset(put,0,sizeof
(put));
70output(time);
71 time++;72}
73 }
DAG上動態規劃 巴比倫塔問題
有n種立方體,每種都有無窮多個,要求選一些立方體摞成一根盡量高的柱子,可以自行選一邊當多高,使得每個立方體的底面長寬分別嚴格小於它下方的立方體的底面長寬。題目鏈結 這個問題可以轉化為乙個dag問題,與矩形巢狀問題類似。轉化過程 將乙個給定的立方體分為三個分別以不同的邊為高的立方體,假如給定立方體為 ...
巴比倫塔的失敗
據 創世紀 記載,巴比倫塔是人類繼諾亞方舟之後的第二大工程壯舉,但巴比倫塔同時也是第乙個徹底失敗的工程。為何擁有了清晰的目標,充足的人力和物力資源的專案最後仍然失敗,巴比倫塔給我們的管理教訓就是它們缺乏溝通和交流,以及交流的結果 組織。他們無法相互交談,從而無法合作。當合作無法進行時,工作陷入了停頓...
巴比倫塔 小強版
include include include include using namespace std int w,n,v,r,t,i,maxn,j multimapmps multimap iterator it2 int state 100 vectorvt void f int num,int...