题目

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. 20155308 实验四 Android开发基础

    20155308 实验四 Android开发基础 实验内容 基于Android Studio开发简单的Android应用并部署测试; 了解Android.组件.布局管理器的使用: 掌握Android中 ...

  2. 20155322 2016-2017-2 《Java程序设计》实验二《Java面向对象程序设计》

    20155322 2016-2017-2 <Java程序设计>实验二<Java面向对象程序设计> 实验目的与内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承 ...

  3. 20155322 2016-2017-2 《Java程序设计》实验一 Java开发环境的熟悉(macOS + Eclipse)

    20155322 2016-2017-2 <Java程序设计>实验一 Java开发环境的熟悉(macOS + Eclipse) 实验目的与内容 熟悉命令行开发环境. 使用vim等文本编译器 ...

  4. 安装虚拟机和Linux系统的学习

    安装虚拟机和Linux系统的学习(随笔3) 1.安装虚拟机 首先我按着老师给的链接上的步骤一步一步安装VirtualBox,进行得十分顺利. 接着则是在虚拟机上安装Ubuntu. 然而安装完成以后按要 ...

  5. 20155330 实验三 敏捷开发与XP实践

    20155330 实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验步骤 (一)敏捷开发与XP 软件工程是把系统的.有序的.可量化的方法应用到软件的开发.运营和维护上的过程. ...

  6. Apache入门篇(四)之LAMP架构部署

    一.LAMP解析 a: apachem: mariadb, mysqlp: php, perl, python 静态资源:静态内容:客户端从服务器获得的资源的表现形式与原文件相同:动态资源:通常是程序 ...

  7. MSP430编译器__intrinsic指令

    1. 在文件intrinsics.c里面发现很多函数前面有__intrinsic,说是这些是MSP430的特定函数(其他单片机用不了),应该和编译器有关,并没有具体的函数实现,我猜测,是直接转成汇编代 ...

  8. eclipse jetty debug

    一.    1, Eeclipse中选择 Run --> External Tools --> External Tools Configurations 然后new一个Program项. ...

  9. git分支在团队中的使用

    须知 在介绍分支常用操作之前 我们需要知道几点: 1.主干不允许做任何修改结构或者业务的操作. 有两种情况可以修改主干: 就是当前主干已经是有问题的,合并后出问题发布不了. 修改与业务无关的配置文件, ...

  10. Wince 中访问WCF服务

    由于本文并非WinCE开发普及篇,所以一些WinCE开发和WCF开发的基础还请移步百度和谷歌寻找答案,然后结合本文开发出WinCE中如何访问WCF,谢谢. 开发环境 IDE:Visual Studio ...