zoukankan      html  css  js  c++  java
  • BZOJ1722 [Usaco2006 Mar] Milk Team Select 产奶比赛

    直接树形dp就好了恩

    令$f[i][j][t]$表示以$i$为根的子树,选出来的点存在$j$对父子关系,$t$表示$i$这个点选或者没选,的最大产奶值

    分类讨论自己和儿子分别有没有选,然后转移一下就好了。。。恩,详情看代码好了

     1 /**************************************************************
     2     Problem: 1722
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:28 ms
     7     Memory:2808 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <algorithm>
    12  
    13 using namespace std;
    14 const int N = 505;
    15 const int inf = 1e9;
    16  
    17 struct edge {
    18     int next, to;
    19     edge(int _n = 0, int _t = 0): next(_n), to(_t) {}
    20 } e[N];
    21  
    22 struct tree_node {
    23     int v, fa;
    24 } tr[N];
    25  
    26 int n, tar, ans;
    27 int first[N], tot;
    28 int f[N][N][2];
    29  
    30 inline void add_edge(int x, int y) {
    31     e[++tot] = edge(first[x], y);
    32     first[x] = tot;
    33 }
    34  
    35 #define y e[x].to
    36 void dfs(int p) {
    37     int t1, t2, tmp, i, j, x;
    38     static int t[N];
    39     f[p][0][0] = 0, f[p][0][1] = tr[p].v;
    40     for (i = 1; i < n; ++i)
    41         f[p][i][0] = f[p][i][1] = -inf;
    42     if (first[p] == 0) return;
    43     for (x = first[p]; x; x = e[x].next) {
    44         dfs(y);
    45         for (t1 = 0; t1 < 2; ++t1) {
    46             for (j = 0; j < n; ++j) t[j] = f[p][j][t1];
    47             for (t2 = 0; t2 < 2; ++t2) {
    48                 tmp = t1 && t2 && p;
    49                 for (i = 0; i < n; ++i) if (f[y][i][t2] != -inf)
    50                     for(j = n - 1; i + tmp <= j; --j)
    51                         if (f[p][j - i - tmp][t1] != -inf)
    52                             t[j] = max(t[j], f[p][j - i - tmp][t1] + f[y][i][t2]);
    53             }
    54             for (j = 0; j < n; ++j) f[p][j][t1] = max(f[p][j][t1], t[j]);
    55         }
    56     }
    57      
    58 }
    59 #undef y
    60  
    61 int main() {
    62     int i;
    63     scanf("%d%d", &n, &tar);
    64     for (i = 1; i <= n; ++i) {
    65         scanf("%d%d", &tr[i].v, &tr[i].fa);
    66         add_edge(tr[i].fa, i);
    67     }
    68     dfs(0);
    69     for (ans = n - 1; ~ans && f[0][ans][0] < tar; --ans);
    70     printf("%d
    ", ans);
    71     return 0;
    72 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    【洛谷P3853】 [TJOI2007]路标设置
    【洛谷P1159】排行榜
    【洛谷P2921】[USACO08DEC]在农场万圣节
    【洛谷P1108】低价购买
    【洛谷P1363】幻象迷宫
    【题解】洛谷P2023 [AHOI2009] 维护序列(线段树)
    【数据结构】线段树的几种用法
    【题解】洛谷P1283 平板涂色(搜索+暴力)
    【题解】洛谷P1074 [NOIP2009TG] 靶形数独(DFS+剪枝)
    【题解】洛谷P1120 小木棍(搜索+剪枝+卡常)
  • 原文地址:https://www.cnblogs.com/rausen/p/4461607.html
Copyright © 2011-2022 走看看