CF816E-Karen and Supermarket
题目
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][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的更多相关文章
- [CF816E] Karen and Supermarket1 [树形dp]
传送门 - > \(CF816E\) Karen and Supermarket 题意翻译 在回家的路上,凯伦决定到超市停下来买一些杂货. 她需要买很多东西,但因为她是学生,所以她的预算仍然很有 ...
- Codeforces 815C Karen and Supermarket 树形dp
Karen and Supermarket 感觉就是很普通的树形dp. dp[ i ][ 0 ][ u ]表示在 i 这棵子树中选择 u 个且 i 不用优惠券的最小花费. dp[ i ][ 1 ][ ...
- CF815C Karen and Supermarket
题目链接 CF815C Karen and Supermarket 题解 只要在最大化数量的前提下,最小化花费就好了 这个数量枚举ok, dp[i][j][1/0]表示节点i的子树中买了j件商品 i ...
- CF815C Karen and Supermarket [树形DP]
题目传送门 Karen and Supermarket On the way home, Karen decided to stop by the supermarket to buy some gr ...
- E. Karen and Supermarket
E. Karen and Supermarket time limit per test 2 seconds memory limit per test 512 megabytes input sta ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- 【Codeforces 815C】Karen and Supermarket
Codeforces 815 C 考虑树型dp. \(dp[i][0/1][k]\)表示现在在第i个节点, 父亲节点有没有选用优惠, 这个子树中买k个节点所需要花的最小代价. 然后转移的时候枚举i的一 ...
随机推荐
- 嵌入式C语言——提取时分秒
嵌入式C语言--提取时分秒 题目: 相关知识点 提取位: 插入位 用宏定义定义地址 #define TIME_Addr 0xFFFFC0000 #define TIME *(volatile int ...
- MySQL入门篇(三)之my.cnf配置文件详解【转】
转自:https://www.cnblogs.com/panwenbin-logs/p/8360703.html #*** client options 相关选项 ***# #以下选项会被MySQL客 ...
- 12、Java并发编程:阻塞队列
Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...
- (转) 理解Angular中的$apply()以及$digest()
原文地址:http://blog.csdn.net/dm_vincent/article/details/38705099 $apply()和$digest()在AngularJS中是两个核心概念,但 ...
- idea css文件不识别的问题的解决方案
可以看到 progressBar不识别 发现仅仅是这一个文件名不识别 所以换一个任意别的文件名即可识别
- 初始CSS模板
/*开始 初始CSS模板 开始*/ body, div, address, blockquote, iframe, ul, ol, dl, dt, dd, li, dl, h1, h2, h3, h4 ...
- python常用模块详解2
序列化模块补充: 1.json格式的限制,json格式的key必须是字符串数据类型 2.json格式的字符串必须是"" 如果数字是key,那么dump之后会强转成字符串数据类型 i ...
- youtube高清视频下载方法
youtube下载方法有多种, 但都不支持1080P以上的高清下载, 今天找到一种支持1080P的, 记录一下 步骤1: 百度搜: Dooseen tubedown 下载该软件, 并安装, 一直下一步 ...
- tikv 安装
export HostIP="127.0.0.1" docker run -d -p 2379:2379 -p 2380:2380 --name pd pingcap/pd \ - ...
- Sublime Text 3高效实用快捷键
2017-11-27 16:18:48 Sublime Text 3 高效实用快捷键 Sublime Text 3 软件及注册码 官网下载链接在这里,有时候会很神奇的上不去,可能是因为被Q了,可能就是 ...