题目

Description

今天Karen要去买东西。

一共有 \(n\) 件物品,每件物品的价格为\(c_i\),同时每件物品都有一张优惠券,可以对这件物品减价 \(d_i\) . 使用第 \(i\) 件物品的优惠券的条件是买这件物品并且使用了第 \(x_i\) 张优惠券。现在给出Karen带的钱数 \(b\) ,问最多能买几件物品。

Input

第一行两个整数 \(n\le 5\times 10^3 , b\le 10^9\) 。

接下来 \(n\) 行中第 \(i\) 行,首先有两个整数 \(c_i,d_i\le 10^9\) 。对于 \(i>1\) 有第三个整数 \(1\le x_i<i\) 。

Output

一行,输出最多能买的物品个数。

Sample Input

样例1:

6 16

10 9

10 5 1

12 2 1

20 18 3

10 2 3

2 1 5

样例2:

5 10

3 1

3 1 1

3 1 2

3 1 3

3 1 4

Sample Output

样例1:

4

样例2:

5

Hint

样例1: 买1,3,4号物品,用优惠券;买6号物品,不用优惠券

样例2:买所有的的物品,用优惠券

分析

由于每个物品只有一件,我们可以把问题转化成求买 \(k\) 个物品至少需要多少钱,最后再统计最多可以买多少个。

由于有 \(1\le x_i<i\) ,所以优惠券的使用条件构成了一棵树。现在问题是如何在这颗树上求解。

注意到如果一个点不用优惠券,那么子树中所有点都不能用,所以设状态:

\(f[x][i][0,1]\) 表示以 \(x\) 为根的子树中买 \(i\) 件物品,是否可以用优惠券(0不能,1能),那么可以通过子树的信息来更新当前点:

\[f[x][i+j][0]=\min \{f[u][i][0]+f[v][j][0],u,v\in \text{subtree}(x)\} \\
f[x][i+j][1]=\min \{f[u][i][1]+f[v][j][1],f[u][i][0]+f[v][j][1],u,v\in \text{subtree}(x)\} \\
\]

即如果当前点不可用优惠券,那么子树都不能用。如果当前点用优惠券,那么子树可用可不用。

这样\(f[\text{root}][k][1]\)就是我们要求的东西。

这样做似乎是\(O(n^3)\)的呢!我们实际上是枚举子树中的点对,所以可以不断地把点合并进当前点中,就可以做到\(n^2\)级别了。

循环的时候要从后往前,否则无法保证每件物品只买一次。

代码

#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long giant;
int read() {
int x=0,f=1;
char c=getchar();
for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
for (;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const int maxn=5e3+10;
const giant inf=1e13;
int n,bud;
giant f[maxn][maxn][2];
vector<int> g[maxn];
void add(int x,int y) {g[x].push_back(y);}
void Min(giant &x,giant y) {x=min(x,y);}
int dfs(int x) {
int sz=1;
for (int v:g[x]) {
int vs=dfs(v);
for (int j=sz;j>=0;--j) {
for (int i=vs;i>=0;--i) {
Min(f[x][i+j][0],f[x][j][0]+f[v][i][0]);
Min(f[x][i+j][1],f[x][j][1]+f[v][i][1]);
}
}
sz+=vs;
}
for (int i=0;i<=n;++i) Min(f[x][i][1],f[x][i][0]);
return sz;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
n=read(),bud=read();
for (int i=1;i<=n;++i) for (int j=0;j<=n;++j) for (int k=0;k<2;++k) f[i][j][k]=inf;
for (int i=1;i<=n;++i) {
f[i][0][0]=0,f[i][1][0]=read(),f[i][1][1]=f[i][1][0]-read();
if (i>1) add(read(),i);
}
dfs(1);
int ans=0;
for (int i=1;i<=n;++i) if (f[1][i][1]<=bud) ans=i;
printf("%d\n",ans);
return 0;
}

CF816E-Karen and Supermarket的更多相关文章

  1. [CF816E] Karen and Supermarket1 [树形dp]

    传送门 - > \(CF816E\) Karen and Supermarket 题意翻译 在回家的路上,凯伦决定到超市停下来买一些杂货. 她需要买很多东西,但因为她是学生,所以她的预算仍然很有 ...

  2. Codeforces 815C Karen and Supermarket 树形dp

    Karen and Supermarket 感觉就是很普通的树形dp. dp[ i ][ 0 ][ u ]表示在 i 这棵子树中选择 u 个且 i 不用优惠券的最小花费. dp[ i ][ 1 ][ ...

  3. CF815C Karen and Supermarket

    题目链接 CF815C Karen and Supermarket 题解 只要在最大化数量的前提下,最小化花费就好了 这个数量枚举ok, dp[i][j][1/0]表示节点i的子树中买了j件商品 i ...

  4. CF815C Karen and Supermarket [树形DP]

    题目传送门 Karen and Supermarket On the way home, Karen decided to stop by the supermarket to buy some gr ...

  5. E. Karen and Supermarket

    E. Karen and Supermarket time limit per test 2 seconds memory limit per test 512 megabytes input sta ...

  6. Codeforces Round #419 (Div. 1) C. Karen and Supermarket 树形DP

    C. Karen and Supermarket     On the way home, Karen decided to stop by the supermarket to buy some g ...

  7. codeforces 815C Karen and Supermarket

    On the way home, Karen decided to stop by the supermarket to buy some groceries. She needs to buy a ...

  8. codeforces round #419 E. Karen and Supermarket

    On the way home, Karen decided to stop by the supermarket to buy some groceries. She needs to buy a ...

  9. Codeforces 815 C Karen and Supermarket

    On the way home, Karen decided to stop by the supermarket to buy some groceries. She needs to buy a ...

  10. 【Codeforces 815C】Karen and Supermarket

    Codeforces 815 C 考虑树型dp. \(dp[i][0/1][k]\)表示现在在第i个节点, 父亲节点有没有选用优惠, 这个子树中买k个节点所需要花的最小代价. 然后转移的时候枚举i的一 ...

随机推荐

  1. 虚拟机安装&Linux初探

    学习基于VirtualBox虚拟机安装Ubuntu图文教程在自己笔记本上安装Linux操作系统 安装虚拟机的过程还算顺利.除了在安装增强设备功能时需要将之前的硬盘弹出之外,没有遇到其他的问题. 通过实 ...

  2. [BZOJ4011][HNOI2015]落忆枫音-[dp乱搞+拓扑排序]

    Description 传送门 Solution 假如我们的图为DAG图,总方案数ans为每个点的入度In相乘(不算1号点).(等同于在每个点的入边选一条边,最后一定构成一棵树). 然而如果加了边x- ...

  3. 4040 EZ系列之奖金 (拓扑)

    4040 EZ系列之奖金 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond         题目描述 Description 由于无敌的WRN在2015年世界英俊帅 ...

  4. LVS入门篇(四)之LVS实战

    一.LVS的NAT模式实战 1.环境说明: HOST OS role remask 192.168.56.12 Centos 7.4 LVS调度器(1.2.7) VIP:192.168.0.104 1 ...

  5. a data verification error occurred, file load failed

    1. 调试创龙DSP6748的时候,下载.out文件出现这个错误 2. 换了其他板子,还有其他仿真器也不行,最后发现是没加载GEL文件

  6. bootstrap 4 panels已被card替换

    https://www.zhihu.com/question/34838389?sort=created 解决问题的思路不对,不应该搜不到就各种着急,应该理清思路, 既然 bootstrap4没有了3 ...

  7. 一个经典的PHP加密解密算法authcode

    项目中有时我们需要使用PHP将特定的信息进行加密,也就是通过加密算法生成一个加密字符串,这个加密后的字符串可以通过解密算法进行解密,便于程序对解密后的信息进行处理.最常见的应用在用户登录以及一些API ...

  8. rpmforge

    Could not retrieve mirrorlist http://mirrorlist.repoforge.org/el6/mirrors-rpmforge error was : PYCUR ...

  9. Unity3D使用NGUI实现简单背包功能

    前话 在许多类型游戏中我们经常会使用到背包,利用背包来设置相应角色属性,多了背包也会让游戏增色拓展不少. 那在Unity3D游戏开发中该如何编写背包系统呢?因为有高人开发了NGUI插件,因此我们进行简 ...

  10. HTML基本代码教学片,认识HTML

    今儿头午有点晕晕的感觉,咳咳,甩甩头开课 HTML 定义:超文本标记语言 (记不住的可以这么记:how to make love ! 哈哈,准备开车,粗人一个,长的不行) 其实理解起来很简单,超越文本 ...