質問の意味:木を考えると、右側には、いくつかのリーフノードがどこにあるかを選択し、右側のパス上のポイント値(合法的なプログラムを見つけて、<=は、リーフノードに来て、少しだけ右葉ノードが存在しますそして、)権の数できるだけそのような選択されたリーフノードという。
解決策:DP +ツリーパケットのバックパック。
1. DPツリーを、それは、木がDPと呼ばれる木があります。
2.グループのバックパック、ここでは主にそのイデオロギーに適用されます。我々は、Fを設定することができます[I] [J]、私は最大のコストの選択ノードjのリーフノードを表し; xの今、そのノードとし、それは以下ですn個のリーフノード(ないその息子)、その後、我々はそれで選挙1,2,3、......、n個のリーフノードの場合を扱いますが、これは木、ノードだけでなく、状態xであるため、その息子によってノードから転送され、そしてその息子のノードとリーフノードが含まれている......
これは、長い葉ノードのノードの数は、この記事のグループ内の項目のx数の息子である一方で、我々は、各ノードXの息子は、この項目のバックパックX基に置かれると考えて、バックパックグループがないようにされていません再帰的な完成は、描画することができたときにノードXから各再帰サブツリーが、我々はDPを実施することができるようになります、戻ってきて、DPは息子(グループ)上で動作するこのグループのバックパックで一回のようなものです答えは、それ;
コードを接続します。
#include <cstdioを> する#include <CStringの> する#include <iostreamの> する#include <アルゴリズム> 使用して 名前空間STDを、 CONSTの INT N = 3E3 + 10 。 const int型 INF = 0x3f3f3f3f 。 INTのN、M。 INT ヴァル[N]。 構造体のエッジは{ int型、Wに対して、次の、 } [N << 4 ]。 int型のヘッド[N]、CNT。 INT FA [N]、サイズ[N]。 INT F [N] [N]、VIS [N]。 無効アドオン(int型のuを、int型 V、INT W){ [ ++ CNT] = (エッジ){ヘッド[U]、V、W}。 ヘッド[U] = CNT。 } INT DFS(INT X){ 場合(ヴァル[X]){ F [X] [ 1 ] = valの[X]。 リターン 1 ; } int型の和= 0 、T。 以下のために(int型 ; I I = I =ヘッド[X] {[I] .next) のint V = [I] .TO。 T = DFS(V)。 合計 + = T; 以下のための(int型 J =合計; j>は=1 ; - j)の ための(INT K = 1 [X] [J] = MAX(F [X] [J]、F [X] [JK] + Fの[F ++ K); K <= T V] [K] - [I] .W)。 } 戻り値の和。 } int型のmain() { scanf関数(" %D%dの"、&N、&M)。 以下のために(int型 I = 1、K、I <=ナノメートル; ++ I){ scanf関数(" %のD "、&K)。 用(INT J = 1 ; J <= K; ++、X、Y J){ scanf関数(" %D%D"&X&Y); (I、x、y)を加える; } } のための(int型 I = N-M + 1 ++ I)のscanf(; iが<= N; " %のD 」、および[I]ヴァル); のmemset(F、 -INF、はsizeof (F)) のために(int型 i = 1 ; iが<= N; I ++)[i]と[F 0 ] = 0 ; DFS(1 ) のために(int型私は= M; I> = 1 ; - I){ 場合(F [ 1 ] [I]> = 0){ printf(" %d個" 、I); 破ります; } } 戻り 0 。 }