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 }
  • 相关阅读:
    用户需求与抱怨的理解:重视用户所关注的核心利益
    有效的沟通,从聆听开始
    Forms 身份验证下“诡异”的Cookie 丢失问题
    Q 语言初学者系列:(2)基本数据类型
    Q 语言初学者系列:(1)开门篇
    熟悉的感觉
    将.NET Entity Framework 的 Cache模块移植到JAVA平台
    [JAVA]你见过这样的switch吗?
    网站上图片"另存为" 为什么是 bmp 格式
    KDB+性能分析:内存篇
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7084119.html
Copyright © 2011-2022 走看看