有n種立方體,每種都有無窮多個,要求選一些立方體摞成一根盡量高的柱子,可以自行選一邊當多高,使得每個立方體的底面長寬分別嚴格小於它下方的立方體的底面長寬。這個問題可以轉化為乙個dag問題,與矩形巢狀問題類似。題目鏈結
轉化過程:將乙個給定的立方體分為三個分別以不同的邊為高的立方體,假如給定立方體為(1,
2,3)
(1,2,3)
(1,2,3
),分成以第乙個數為高的三個立方體:(1,
2,3)
(1,2,3)
(1,2,3
)、(2,1
,3
)(2,1,3)
(2,1,3
)和(3,2
,1
)(3,2,1)
(3,2,1
)(注意:(2,
3,1)
(2,3,1)
(2,3,1
)和(2,1
,3
)(2,1,3)
(2,1,3
)是相同的狀態),這樣任何乙個節點就不可能指向自己。
假如給了30個立方體,就可以組成乙個有90個節點的有向無環圖,假如 x 狀態可以放在 y 狀態的上面,則說 x 指向 y 。然後可以給這 90 個立方體狀態編號。
for
(int ii=
0;ii)}
建立圖:
for
(int i=
0;i3;i++)}
}
使用記憶化搜尋的方法尋找最長路徑。
狀態轉移方程為:
d (i
)=ma
xd(i)=max\left \
d(i)=m
axf (i
)f(i)
f(i)
為 ii
i 節點立方體的高。
intdp(
int i)
return ans;
}
完整程式:
#define local
#include
#include
#include
#include
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define maxn 92
using
namespace std;
int n;
//儲存圖的鄰接矩陣
int g[maxn]
[maxn]
;int d[maxn]
;//以陣列來記錄圖中的點,陣列第乙個數表示高,二三表示長和寬
int towernode[maxn][3
];//計算i節點的深度
intdp
(int i)
return ans;
}int
main()
}for
(int i=
0;i3;i++)}
}for
(int i=
0;i3;i++
) cout <<
"case "
<< n <<
": maximum height = "
<<
*max_element
(d,d+maxn)
<<
"\n";}
return0;
}
動態規劃 巴比倫塔
做了一道zoj上的題目,發現是一道經典原題的改編 只改了題目背景。資料都一樣 zoj problem set 1093 解題報告 題目分類 動態規劃 題目大意 有n種木塊,每種都是無限提供,木塊可以隨意擺放 即每條邊都可能為高 當某一塊木塊的長和寬都小於下面的木塊時,才能疊在上面。要求最高能疊多高。...
UVA 437 巴比倫塔(DAG上的動態規劃
紅書上的動態規劃專題 題意 有n種立方體,每種都有無窮多個,要求選一些立方體摞成一根盡量高的柱子,可以自行選一邊當多高,使得每個立方體的底面長寬分別嚴格小於它下方的立方體的底面長寬 思路 各個立方體 能否被摞 關係是乙個典型的二元關係,二元關係可以用圖來建模,如果b能摞在a上,a到b就有一條有邊向,...
巴比倫塔的失敗
據 創世紀 記載,巴比倫塔是人類繼諾亞方舟之後的第二大工程壯舉,但巴比倫塔同時也是第乙個徹底失敗的工程。為何擁有了清晰的目標,充足的人力和物力資源的專案最後仍然失敗,巴比倫塔給我們的管理教訓就是它們缺乏溝通和交流,以及交流的結果 組織。他們無法相互交談,從而無法合作。當合作無法進行時,工作陷入了停頓...