• 通向自由的钥匙


    通向自由的钥匙被放n个房间里,这n个房间由n-1条走廊连接。但是每个房间里都有特别的保护魔法,在它的作用下,我无法通过这个房间,也无法取得其中的钥匙。虽然我可以通过消耗能量来破坏房间里的魔法,但是我的能量是有限的。那么,如果我最先站在1号房间(1号房间的保护魔法依然是有效的,也就是,如果不耗费能量,我无法通过1号房间,也无法取得房间中的钥匙),如果我拥有的能量为P,我最多能取得多少钥匙?

    输入数据
        第一行包含两个非负整数,第一个为N,第二个为P。
        接下来n行,按1~n的顺序描述了每个房间。第i+1行包含两个非负整数cost和keys,分别为第i件房取消魔法需要耗费的能量和房间内钥匙的数量。
        接下来n-1行,每行两个非负整数x,y,表示x号房间和y号是连通的。

    输出数据
        一行一个整数,表示取得钥匙的最大值。

    样例
    输入:key.in
    5 5
    1 2
    1 1
    1 1
    2 3
    3 4
    1 2
    1 3
    2 4
    2 5

    输出: key.out
    7

    一道树形dp基础题。

    dfs后,两层循环都要倒着枚举。第一层循环是因为分组背包要倒着,第二层循环是因为有c = 0的情况。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 typedef long long ll;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const db eps = 1e-8;
    20 const int maxn = 105;
    21 inline ll read()
    22 {
    23   ll ans = 0;
    24   char ch = getchar(), last = ' ';
    25   while(!isdigit(ch)) last = ch, ch = getchar();
    26   while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
    27   if(last == '-') ans = -ans;
    28   return ans;
    29 }
    30 inline void write(ll x)
    31 {
    32   if(x < 0) x = -x, putchar('-');
    33   if(x >= 10) write(x / 10);
    34   putchar(x % 10 + '0');
    35 }
    36 void MYFILE()
    37 {
    38 #ifndef mrclr
    39   freopen("key.in", "r", stdin);
    40   freopen("key.out", "w", stdout);
    41 #endif
    42 }
    43 
    44 int n, p;
    45 int c[maxn], k[maxn];
    46 struct Edge
    47 {
    48   int nxt, to;
    49 }e[maxn << 1];
    50 int head[maxn], ecnt = -1;
    51 void addEdge(int x, int y)
    52 {
    53   e[++ecnt] = (Edge){head[x], y};
    54   head[x] = ecnt;
    55 }
    56 
    57 ll dp[maxn][maxn];
    58 void dfs(int now, int f)
    59 {
    60   for(int i = c[now]; i <= p; ++i) dp[now][i] = k[now];     //赋初值
    61   for(int i = head[now]; i != -1; i = e[i].nxt)
    62     {
    63       if(e[i].to == f) continue;
    64       dfs(e[i].to, now);
    65       for(int j = p; j >= c[now]; --j)
    66       for(int h = j; h >= c[now]; --h)
    67           dp[now][j] = max(dp[now][j], dp[now][h] + dp[e[i].to][j - h]);
    68     }
    69 }
    70 
    71 int main()
    72 {
    73   MYFILE();
    74   Mem(head, -1);
    75   n = read(); p = read();
    76   for(int i = 1; i <= n; ++i) c[i] = read(), k[i] = read();
    77   for(int i = 1; i < n; ++i)
    78     {
    79       int x = read(), y = read();
    80       addEdge(x, y); addEdge(y, x);
    81     }
    82   dfs(1, 0);
    83   write(dp[1][p]), enter;
    84   return 0;
    85 }
    View Code

    还自己yy了一个O(nv)的算法,虽然过了,然而忘了怎么写的……

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 typedef long long ll;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const db eps = 1e-8;
    20 const int maxn = 105;
    21 inline ll read()
    22 {
    23   ll ans = 0;
    24   char ch = getchar(), last = ' ';
    25   while(!isdigit(ch)) last = ch, ch = getchar();
    26   while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
    27   if(last == '-') ans = -ans;
    28   return ans;
    29 }
    30 inline void write(ll x)
    31 {
    32   if(x < 0) x = -x, putchar('-');
    33   if(x >= 10) write(x / 10);
    34   putchar(x % 10 + '0');
    35 }
    36 void MYFILE()
    37 {
    38 #ifndef mrclr
    39   freopen("key.in", "r", stdin);
    40   freopen("key.out", "w", stdout);
    41 #endif
    42 }
    43 
    44 int n, p;
    45 int c[maxn], k[maxn];
    46 struct Edge
    47 {
    48   int nxt, to;
    49 }e[maxn << 1];
    50 int head[maxn], ecnt = -1;
    51 void addEdge(int x, int y)
    52 {
    53   e[++ecnt] = (Edge){head[x], y};
    54   head[x] = ecnt;
    55 }
    56 
    57 ll dp[maxn][maxn];
    58 void dfs(int now, int f, int x)
    59 {
    60   if(x < 0) return;
    61   for(int i = head[now]; i != -1; i = e[i].nxt)
    62     {
    63       if(e[i].to == f) continue;
    64       for(int j = 0; j <= x; ++j) dp[e[i].to][j] = dp[now][j];
    65       dfs(e[i].to, now, x - c[e[i].to]);
    66       for(int j = c[e[i].to]; j <= p; ++j)
    67       dp[now][j] = max(dp[now][j], dp[e[i].to][j - c[e[i].to]] + k[e[i].to]);
    68     }
    69 }
    70 
    71 int main()
    72 {
    73   MYFILE();
    74   Mem(head, -1);
    75   n = read(); p = read();
    76   for(int i = 1; i <= n; ++i) c[i] = read(), k[i] = read();
    77   for(int i = 1; i < n; ++i)
    78     {
    79       int x = read(), y = read();
    80       addEdge(x, y); addEdge(y, x);
    81     }
    82   addEdge(0, 1);
    83   dfs(0, -1, p);
    84   write(dp[0][p]), enter;
    85   return 0;
    86 }
    View Code
  • 相关阅读:
    代码管理工具SonarQube的搭建和使用
    WebFlux Logs日志
    WebFlux WebClient异常处理
    WebFlux- WebClient(二)
    WebFlux- WebClient(一)
    WebFlux-Server-Sent Event服务器推送事件
    Reactive Stack
    Flink
    Gradle
    springboot
  • 原文地址:https://www.cnblogs.com/mrclr/p/9894985.html
Copyright © 2020-2023  润新知