zcmu 5142 巴比倫塔

2021-10-18 04:52:48 字數 3851 閱讀 1879

有n(n<=30)種磚塊,已知三條邊長,每種都有無窮多個。要求選一些立方體摞成一根盡量高的柱子(每個磚塊可以自行選擇一條邊作為高),使得每個磚塊的底面長寬分別嚴格小於它下方磚塊的底面長寬,求塔的最大高度。(多組輸入,有n == 0的情況,資料都在int範圍內)

第一行 t 組 n

n個方磚

a,b,c磚的三維.

(t<=100,n<=30,0<= a,b,c<=1e6)

見樣例4

110 20 30

26 8 10

5 5 5

71 1 1

2 2 2

3 3 3

4 4 4

5 5 5

6 6 6

7 7 7

531 41 59

26 53 58

97 93 23

84 62 64

33 83 27

case 1: maximum height = 40

case 2: maximum height = 21

case 3: maximum height = 28

case 4: maximum height = 342

由於每個磚塊的底面長寬分別嚴格小於它下方磚塊的底面長寬,因此不難將這樣一種關係作為建圖

的依據,而本題也就轉化為最長路問題。

也就是說如果磚塊j能放在磚塊i.上,那麼i和j之間存在一邊(i,j),且邊權就是磚塊j所選取的高。

本題的另乙個問題在於每個磚塊的高有三種選法,怎樣建圖更合適呢?

不妨將每個磚塊拆解為三種堆疊方式,即將乙個磚塊分解為三個磚塊, 每乙個拆解得到的磚塊都選取不同的高。

初始的起點是大地,大地的底面是無窮大的,則大地可達任意磚塊,當然我們寫程式時不必特意寫上無窮大。

假設有兩個磚塊,三條邊分別為31, 41, 59和33, 83, 27,那麼整張dag應該如下圖所示。

圖中藍實框所表示的是乙個磚塊拆解得到的一組磚塊,之所以用{}示底面長寬,因為磚塊一旦選取了高,底面邊長就是無序的。

圖中黃虛框表示的是重複計算部分,為下文做鋪墊。

題目要求的是塔的最大高度,已經轉化為最長路問題,其起點上文已指出是大地,那麼終點呢?

顯然終點已經自然確定,那就是某磚塊上不能再搭別的磚塊的時候。

之前在圖上標記的黃虛框表明有重複計算,下面我們開始考 慮轉移方程。

顯然,磚塊- -旦選取了高,那麼這塊磚塊上最大能放的高度是確定的。

某個磚塊i有三種堆疊方式分別記為0,1,2,那麼對於磚塊i和其堆疊方式r來說則有如下轉移方程

d(i,r)= max

其中j是所有那些在磚塊i以r方式堆疊時可放上的磚塊,r』 對應j此時的擺放方式,也就確定了此時唯一的高度h』。

在實際編寫時,將所有d(i, r)都初始化為-1,表示未計算過。

在試圖計算前,如果發現已經計算過,直接返回儲存的值;否則就按步計算,並儲存。

最終答案是所有d(i,r)的最大值。

//code1

//andong 2021/1/29

//#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define inf 0x3f3f3f3f

#define ll long long

#define ll long long

#define maxn (1000 + 5)

#define max(a, b) (((a) > (b)) ? (a) : (b))

using

namespace std;

int d[maxn][3

];int x[maxn]

, y[maxn]

, z[maxn]

;int

babylon_sub

(int c,

int rot,

int n)

d[c]

[rot]=0

;int base1, base2;

if(rot ==0)

if(rot ==1)

if(rot ==2)

for(

int i =

0; i < n; i++

)return d[c]

[rot];}

intbabylon

(int n)

int r =0;

for(

int i =

0; i < n; i++

)return r;

}int

main()

cout <<

"case "

<< t <<

":"<<

" maximum height = "

<<

babylon

(n);

cout << endl;

}return0;

}

稍微用了一點拓撲的思路在處理dag上加速了

//code2

//andong 2021/1/29

//#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define inf 0x3f3f3f3f

#define ll long long

#define ll long long

using

namespace std;

const

int maxn =

1e3+10;

const ll mod =

1e9+7;

int a[maxn]

,b[maxn]

,c[maxn]

;struct node p[maxn]

;vector<

int>e[maxn]

;int in[maxn]

,ans[maxn]

;int

main()

n=n*3;

for(

int i=

0; i

(p[i]

.c>p[j]

.c&&p[i]

.l>p[j]

.l)}

} queue<

int>num;

for(

int i=

0; i

int ans=0;

while

(!num.

empty()

) ans=

max(ans,ans[tmp]);

}printf

("case %d: maximum height = %d\n"

,++cas,ans);}

return0;

}

巴比倫塔的失敗

據 創世紀 記載,巴比倫塔是人類繼諾亞方舟之後的第二大工程壯舉,但巴比倫塔同時也是第乙個徹底失敗的工程。為何擁有了清晰的目標,充足的人力和物力資源的專案最後仍然失敗,巴比倫塔給我們的管理教訓就是它們缺乏溝通和交流,以及交流的結果 組織。他們無法相互交談,從而無法合作。當合作無法進行時,工作陷入了停頓...

巴比倫塔 小強版

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...

動態規劃 巴比倫塔

做了一道zoj上的題目,發現是一道經典原題的改編 只改了題目背景。資料都一樣 zoj problem set 1093 解題報告 題目分類 動態規劃 題目大意 有n種木塊,每種都是無限提供,木塊可以隨意擺放 即每條邊都可能為高 當某一塊木塊的長和寬都小於下面的木塊時,才能疊在上面。要求最高能疊多高。...