有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種木塊,每種都是無限提供,木塊可以隨意擺放 即每條邊都可能為高 當某一塊木塊的長和寬都小於下面的木塊時,才能疊在上面。要求最高能疊多高。...