【問題描述】
傳說中的九頭龍是一種特別貪吃的動物。雖然名字叫「九頭龍」,但這只是說它出生的時候有九個頭,而在成長的過程中,它有時會長出很多的新頭,頭的總數會遠大於九,當然也會有舊頭因衰老而自己脫落。
有一天,有 m 個腦袋的九頭龍看到一棵長有 n 個果子的果樹,喜出望外,恨不得一口把它全部吃掉。可是必須照顧到每個頭,因此它需要把 n 個果子分成 m 組,每組至少有乙個果子,讓每個頭吃一組。
這 m 個腦袋中有乙個最大,稱為「大頭」,是眾頭之首, 它要吃掉恰好 k 個果子,而且 k 個果子中理所當然地應該包括唯一的乙個最大的果子。 果子由 n-1根樹枝連線起來,由於果樹是乙個整體,因此可以從任意乙個果子出發沿著樹枝「走到」任何乙個其他的果子。
對於每段樹枝,如果它所連線的兩個果子需要由不同的頭來吃掉,那麼兩個頭會共同把樹枝弄斷而把果子分開;如果這兩個果子是由同乙個頭來吃掉,那麼這個頭會懶得把它弄斷而直接把果子連同樹枝一起吃掉。當然,吃樹枝並不是很舒服的,因此每段樹枝都有乙個吃下去的「難受值」,而九頭龍的難受值就是所有頭吃掉的樹枝的「難受值」之和。
九頭龍希望它的「難受值」盡量小,你能幫它算算嗎?
例如圖 1 所示的例子中,果樹包含 8 個果子,7 段樹枝,各段樹枝的「難受值」標記在了樹枝的旁邊。九頭龍有兩個腦袋,大頭需要吃掉 4 個果子,其中必須包含最大的果子。即 n=8,m=2,k=4:
最大的果子大頭吃 4 個果子,用實心點標識;小頭吃 4 個果子,用空心點標識;九頭龍的難受值為 4,因為圖中用細邊標記的樹枝被大頭吃掉了。
【輸入檔案】
輸入檔案 dragon.in 的第 1 行包含三個整數 n (1<=n<=300), m (2<=m<=n),k (1<=k<=n)。 n 個果子依次編號 1,2,...,n,且 最大的果子的編號總是 1。
第 2行到第 n 行描述了果樹的形態,每行包含三個整數 a (1<=a<=n), b (1<=b<=n),c (0<=c<=10 5 ),表示存在一段難受值為 c 的樹枝連線果子 a 和果子 b。
【輸出檔案】
輸出檔案 dragon.out 僅有一行,包含乙個整數,表示在滿足「大頭」的要求的前提下,九頭龍的難受值的最小值。如果無法滿足要求,輸出-1。
【樣例輸入】
8 2 4
1 2 20
1 3 4
1 4 13
2 5 10
2 6 12
3 7 15
3 8 5
【樣例輸出】
4【樣例說明】
該樣例對應於題目描述中的例子。
正解:樹形dp
解題報告:
今天考試t4,居然是noi原題。
顯然是一道樹形dp,但是我們考慮記錄的狀態是什麼:f[0、1][i][j]表示以i為根結點的子樹中1號吃了j個並且i不選或者選的最小值。同時記憶化。
直接分類討論兒子結點選了多少個,總複雜度o(n^3)。
**如下:
1//it is made by jump~
2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include
13using
namespace
std;
14 typedef long
long
ll;15
const
int maxn = 311;16
ll inf;
17int
n,m,k,ecnt;
18int first[maxn],next[maxn*2],to[maxn*2
];19
intbrother[maxn],son[maxn],lian[maxn][maxn];
20bool
vis[maxn];
21 ll f[2
][maxn][maxn];
2223 inline int
getint()
2429
30 inline void down(int x,int
fa)37}38
39 inline ll dfs(int x,int fa,int remain,int
flag)
41if(f[flag][x][remain]!=-1) return
f[flag][x][remain];
42 ll minl=inf,nowl,nowr,suan;
43for(int i=0;i<=remain;i++) else suan=nowl+nowr;
50if(suan51
*/52
53if(nowl>=0 && nowr>=0
) else suan=nowl+nowr;
55 minl=min(minl,suan);
56}
57 nowr=dfs(son[x],x,remain-i,0);//
不選58
/*if(nowl>=0)
*/62
if(nowl>=0 && nowr>=0
) 66}67
//printf("%d %d %d %d\n",x,fa,remain,flag);
68if(minl==inf) f[flag][x][remain]=-inf; else f[flag][x][remain]=minl;
69return
f[flag][x][remain];70}
7172 inline void
work()
80if(m-1+k>n)
81 down(1,0); memset(f,-1,sizeof
(f));
82 dfs(son[1],1,k-1,1
);83 printf("
%lld
",f[1][son[1]][k-1
]);84}85
86int
main()
87
codevs 1746 貪吃的九頭龍
狀態定義的沒錯 就是考試的時候傻啦吧唧的轉移左右孩子 其實之轉移父親就簡單多了 不用考慮那麼多 還有就是偷懶沒有把誰有沒有找過這個資訊轉過去 而是搞了個全域性變數 wa到挺 再就是特盤的時候還有終止條件寫的不好 寫的時間也很長 include include include define maxn ...
貪吃的九頭龍
傳說中的九頭龍是一種特別貪吃的動物。雖然名字叫 九頭龍 但這只是說它出生的時候有九個 頭,而在成長的過程中,它有時會長出很多的新頭,頭的總數會遠大於九,當然也會有舊頭因衰老而自己脫落。有一天,有 m 個腦袋的九頭龍看到一棵長有 n個果子的果樹,喜出望外,恨不得一口把它全部吃掉。可是必須照顧到每個頭,...
貪吃的九頭龍
時間限制 2 sec 記憶體限制 128 mb 提交 57 解決 22 提交 狀態 我的提交 傳說中的九頭龍是一種特別貪吃的動物。雖然名字叫 九頭龍 但這只是說它出生的時候有九個頭,而在成長的過程中,它有時會長出很多的新頭,頭的總數會遠大於九,當然也會有舊頭因衰老而自己脫落。有一天,有m 個腦袋的九...