codevs1746 貪吃的九頭龍

2022-05-08 05:39:11 字數 3016 閱讀 7064

【問題描述】

傳說中的九頭龍是一種特別貪吃的動物。雖然名字叫「九頭龍」,但這只是說它出生的時候有九個頭,而在成長的過程中,它有時會長出很多的新頭,頭的總數會遠大於九,當然也會有舊頭因衰老而自己脫落。

有一天,有 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 個腦袋的九...