zoukankan      html  css  js  c++  java
  • EOJ 2103 小强寻宝I

    http://www.acm.cs.ecnu.edu.cn/problem.php?problemid=2103

    树型dp + 分组背包。

      dp[u][V]表示 对于以根为u的子树、剩余pow为V(看作容量)时能得到的最优解,那么:

      对于u的某一个状态dp[u][k]:

        其子树vi有 size( dp[vi][j] ) 个状态,但仅有一个状态可以转移给 dp[u][k] ,所以必须以子树为单位分组。

    关于分组背包,详细请看:

      http://blog.csdn.net/nywsp/article/details/7737158

     1 #include<map>
     2 #include<set>
     3 #include<list>
     4 #include<cmath>
     5 #include<ctime>
     6 #include<queue>
     7 #include<stack>
     8 #include<cctype>
     9 #include<cstdio>
    10 #include<string>
    11 #include<vector>
    12 #include<cstdlib>
    13 #include<cstring>
    14 #include<iostream>
    15 #include<algorithm>
    16 #define MAXN 105
    17 using namespace std;
    18  
    19 int dp[MAXN][MAXN], v[MAXN];
    20 int c[MAXN], w[MAXN];
    21 int ans;
    22 vector<int> g[MAXN];
    23  
    24 void dfs(int u, int pu){    //分组背包,一棵子树为一组
    25     v[u] = 1;
    26     if(pu-c[u] < 0)
    27         return ;
    28     for(int j=c[u]; j<=pu; j++)
    29         dp[u][j] = w[u];
    30     for(int i=0; i<g[u].size(); i++){    //组数
    31         if(v[g[u][i]])
    32             continue;
    33         dfs(g[u][i], pu-c[u]);
    34         for(int j=pu; j>=c[u]; j--)        //注意此for逆序,且在中间
    35             for(int k=c[g[u][i]]; k<=j-c[u]; k++)    //每组至多只取一个
    36                 dp[u][j] = max(dp[u][j], dp[u][j-k]+dp[g[u][i]][k]);
    37     }
    38 }
    39  
    40 int main()
    41 {
    42     int n, p;
    43     while(cin >> n >> p){
    44         if(n == 0){
    45             printf("0
    ");
    46             continue;
    47         }
    48         for(int i=1; i<=n; i++)
    49             scanf("%d%d", &c[i], &w[i]);
    50         for(int i=1; i<=n-1; i++){
    51             int a, b;
    52             scanf("%d%d", &a, &b);
    53             g[a].push_back(b);
    54             g[b].push_back(a);
    55         }
    56         int root=1;
    57         memset(v, 0, sizeof(v));
    58         memset(dp, 0, sizeof(dp));
    59         dfs(root, p);
    60         if(p < c[root])
    61             printf("0
    ");
    62         else
    63             printf("%d
    ", dp[root][p]);
    64         for(int i=1; i<=n; i++)
    65             g[i].clear();
    66     }
    67  
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    准备工作
    个人作业感言
    年度书单-结对编程
    案例分析
    编程作业_词频统计
    2、阅读任务
    1、准备工作
    个人作业获奖感言
    3 20210405-1 案例分析作业
    202103226-1 编程作业
  • 原文地址:https://www.cnblogs.com/KimKyeYu/p/3315698.html
Copyright © 2011-2022 走看看