题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011
dp[u][i]为以u为根节点的,花了不超过i元钱能够得到的最大价值
因为题目里说要访问子节点必须先访问根节点,所以
dp[u][i+j] = max(dp[u][i],dp[u][i]+dp[v][j]); v是u的儿子节点。
代码:
1 import java.util.*; 2 import static java.lang.Math.*; 3 4 class Graph{ 5 ArrayList<ArrayList<Integer>> e; 6 int dp[][]; 7 boolean vis[]; 8 int n,m; 9 public Graph(int n,int m){ 10 e = new ArrayList<ArrayList<Integer>>(); 11 for(int i=0;i<=n;i++){ 12 e.add(new ArrayList<Integer>()); 13 } 14 dp = new int[n+1][m+1]; 15 vis = new boolean[n+1]; 16 this.n = n; 17 this.m = m; 18 } 19 20 public void add_edge(int from,int to){ 21 ArrayList<Integer> t = e.get(from); 22 t.add(to); 23 } 24 25 public int dfs(int u){ 26 if( vis[u] ) return 0; 27 vis[u] = true; 28 29 ArrayList<Integer> t = e.get(u); 30 31 for(int i=m;i>=Main.w[u];i--) dp[u][i] = Main.v[u]; 32 33 for(int s:t ){ 34 if( vis[s] ) continue; 35 dfs(s); 36 37 for(int i=m;i>=Main.w[u];i--){ 38 for(int j=1;j<=m;j++){ 39 if( i+j<=m ){ 40 dp[u][i+j] =max(dp[u][i+j], dp[u][i]+dp[s][j]); 41 } 42 } 43 } 44 } 45 return dp[u][m]; 46 } 47 48 } 49 50 51 public class Main{ 52 static int N,M; 53 static Scanner sc = new Scanner(System.in); 54 static int w[],v[]; 55 public static void main(String[] args){ 56 while( sc.hasNext() ){ 57 58 N = sc.nextInt(); 59 M = sc.nextInt(); 60 61 if( N==-1 && M==-1 ) break; 62 63 w = new int[N+1]; 64 v = new int[N+1]; 65 66 Graph g = new Graph(N,M); 67 68 for(int i=1;i<=N;i++){ 69 w[i] = sc.nextInt(); 70 v[i] = sc.nextInt(); 71 w[i] = (w[i]+19)/20; 72 } 73 74 for(int i=1;i<N;i++){ 75 int a = sc.nextInt(); 76 int b = sc.nextInt(); 77 g.add_edge(a,b); 78 g.add_edge(b,a); 79 } 80 81 if( M==0 ){ 82 System.out.println(0); 83 continue; 84 } 85 86 int ans = g.dfs(1); 87 System.out.println(ans); 88 89 } 90 91 } 92 93 94 }
浙公网安备 33010602011771号