トピックリンクします。https://vjudge.net/problem/POJ-2486
最大のポイントとm個のエッジまでに権利を求めた後、木の右のポイント、出発点1:質問の意味。
アイデア:
古典的なタイトルDPツリー。3次元の状態で、DPは、[U]は[j]は[0/1]サブツリーのuの最大値jテイクステップを(バックuは/ Uに戻らない)を表します。明らかDP [U] [J] [1]> = DP [U] [j] [0]、[1]最終的な答えである[1] [M] DPので。
次のように仮定するVは、使用されるkおよびvはVのステップ数であり、3つの段階で転写式Uの子ノードです。
DP [U] [j] [0] = MAX(DP [U] [j] [0]、DP [U] [JK] [0] + DP [V] [K-2] [0])(K > = 2)
DP [U] [J] [1] = MAX(DP [U] [J] [1]、DP [U] [JK] [0] + DP [V] [K-1] [1])(K > = 1)
DP [U] [J] [1] = MAX(DP [U] [J] [1]、DP [U] [JK] [1] + DP [V] [K-2] [0])(K > = 2)(ステップ3忘れやすいです)
ACコード:
書式#include <cstdioを> する#include <アルゴリズム> 使用して 名前空間はstdを、 const int型 MAXN = 105 ; const int型 MAXM = 205 ; INTの N、M、CNT、[MAXN]、ヘッド[MAXN]、DP [MAXN] [MAXM] [ 2 ]。 構造体ノード{ int型V、NEX。 }エッジ[MAXN << 1 ]。 ボイド ADDE(INT U、INT V){ エッジ[ ++ CNT] .V = V。 エッジ[CNT] .nex = 頭部[U]。 ヘッド[U] = CNT。 } ボイド DFS(INT U、INT FA){ ため(int型 I =ヘッド[U]; I; I = エッジ[I] .nex){ int型 V = エッジ[I] .V。 もし(== FA V)続けます。 DFS(V、U); 用(INT J = M; J> = 1 ; - j)の ための(INT K = 1 ; K <= J; ++ K){ 場合(k> = 2)DP [U] [j] [ 0 ] = MAX(DP [U] [j] [ 0 ]、DP [U] [JK] [ 0 ] + DP [V] [K- 2 ] [0 ])。 もし(K> = 1)DP [U] [J] [ 1 ] = MAX(DP [U] [J] [ 1 ]、DP [U] [JK] [ 0 ] + DP [V] [K- 1 ] [ 1 ])。 もし(K> = 2)DP [U] [J] [ 1 ] = MAX(DP [U] [J] [ 1 ]、DP [U] [JK] [ 1 ] + DP [V] [K- 2 ] [ 0 ])。 } } } int型のmain(){ ながら(〜のscanf(" %d個の%のD "、&N、&M)){ CNT = 0 。 以下のために(int型私= 1 ++; iが<= N I) のscanf(" %dの"、および[I])。 以下のために(int型 i = 1 ; iは= N <; ++ I){ ヘッド[I] = 0 ; 用(INT J = 0 ; J <= M; ++ j)は DP [I] [J] [ 0 ] = DP [i] [j]は、[ 1 ] = [I]。 } のために(int型 i = 1 ; iがn <; ++ I){ int型 Uを、V。 scanf関数(" %d個の%d個"、&U&V); ADDE(U、V); ADDE(V、U); } DFS(1、0 ); printf(" %d個の\ n "、DP [ 1 ] [M] [ 1 ])。 } 戻り 0 。 }