zoukankan      html  css  js  c++  java
  • Codeforces Round #419 (Div. 2) E. Karen and Supermarket(树形dp)

    http://codeforces.com/contest/816/problem/E

    题意:

    去超市买东西,共有m块钱,每件商品有优惠卷可用,前提是xi商品的优惠券被用。问最多能买多少件商品?

    思路:

    第一件商品使用优惠券不需要前提,别的都是需要的,然后这样就形成了一棵以1为根的树。

    这样,很容易想到是树形dp。

    d【u】【j】【0/1】表示以u为根的子数中选择j件商品所需的最少花费,0/1表示u商品是否能用优惠券。

    解释一下代码中的sz【】,它所代表的是以u为根的子树的结点数。

    当我们现在访问的是1号结点时,sz【1】=1,然后访问2号结点,2号结点访问结束后,我们就会重新回到1号结点的dfs处,然后进行状态转移

     for(int j=sz[u];j>=0;j--)   //表示sz【u】中选取的j个个数
    
     for(int k=0;k<=sz[v];k++)   //表示v结点及其子树中选取的个数

    最后将sz【2】的值加到sz【1】中,这样等下一次进行结点3的状态转移时,只需要考虑在2的子树中选取多少个和3的子树中选取多少个即可。到4时,只需要考虑在2和3中一共选取多少个和4的子树中选取多少个,因为前者在上一步已经计算出了最小花费。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<sstream>
     6 #include<vector>
     7 #include<stack>
     8 #include<queue>
     9 #include<cmath>
    10 #include<map>
    11 #include<set>
    12 using namespace std;
    13 typedef long long ll;
    14 typedef pair<int,int> pll;
    15 const int INF = 0x3f3f3f3f;
    16 const int maxn = 5000+5;
    17 
    18 int n, m;
    19 
    20 int pa[maxn], pb[maxn];
    21 int sz[maxn];
    22 int d[maxn][maxn][2];
    23 
    24 vector<int> g[maxn];
    25 
    26 void dfs(int u)
    27 {
    28     sz[u]=1;
    29     d[u][0][0]=0, d[u][1][0]=pa[u], d[u][1][1]=pa[u]-pb[u];
    30     for(int i=0;i<g[u].size();i++)
    31     {
    32         int v=g[u][i];
    33         dfs(v);
    34 
    35         for(int j=sz[u];j>=0;j--)
    36         {
    37             for(int k=0;k<=sz[v];k++)
    38             {
    39                 d[u][j+k][0]=min(d[u][j+k][0],d[u][j][0]+d[v][k][0]);
    40                 d[u][j+k][1]=min(d[u][j+k][1],min(d[u][j][1]+d[v][k][1],d[u][j][1]+d[v][k][0]));
    41             }
    42         }
    43         sz[u]+=sz[v];
    44     }
    45 }
    46 
    47 int main()
    48 {
    49     //freopen("in.txt","r",stdin);
    50     while(~scanf("%d%d",&n, &m))
    51     {
    52         for(int i=1;i<=n;i++)  g[i].clear();
    53         for(int i=1;i<=n;i++)
    54         {
    55             scanf("%d%d",&pa[i],&pb[i]);
    56             if(i>1)
    57             {
    58                 int x;
    59                 scanf("%d",&x);
    60                 g[x].push_back(i);
    61             }
    62         }
    63 
    64         memset(d,INF,sizeof(d));
    65         dfs(1);
    66 
    67         int i;
    68         for(i=0;i<=n;i++)
    69         {
    70             if(min(d[1][i][0],d[1][i][1])>m)   break;
    71         }
    72         printf("%d
    ",i-1);
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    eletron打包
    助力ASP.NET Core 2.1开发!Layx 企业级弹窗插件发布!
    springcloud 入门 3 (服务之间的调用)
    springcloud 入门 2 (Enreka的服务和注册)
    springcloud 入门 1 (浅谈版本关系)
    springboot 学习之路 18(webflux详细介绍(2))
    springboot 学习之路 17(webflux 入门 (1))
    springboot 学习之路 15(集成shiro)
    Mongodb的入门(6)副本集
    Mongodb的入门(4)mongodb3.6的索引
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7084119.html
Copyright © 2011-2022 走看看