cf 816E Karen and Supermarket
题目大意
给定\(n\)一颗树,每个点上有一个物品
每个物品有价格\(c[i]\)
有优惠券,能使价格减少\(d[i]\)
但是使用优惠券的前提时购买该物品,且父亲也使用优惠券
给定钱包余额\(lim\)
求最多能买多少物品
\(n\le 5000, c[i],d[i],lim\le 10^9\)
分析
树上背包
由于价值的数字很大,不能用钱来表示状态,个数表示dp值
只能先计算购买\(k\)个的最少价钱,再判断限制
\(f[x][i][0]\)表示\(x\)这个点不用优惠券,子树中买了\(i\)个物品的最低价钱
\(f[x][i][1]\)表示\(x\)这个点不用优惠券,子树中买了\(i\)个物品的最低价钱
使用子树不断合并到当前点的方法,可以使复杂度变为\(n^2\)
(每个点对在贡献一次\(O(1)\)复杂度后合并到一个状态中,相互不会再产生贡献)
做法
记\(x\)为当前点,\(y\)为该点的儿子
边界条件
f[x][0][0]=0 ,f[x][0][1]=INF
f[x][1][0]=c[i], f[x][1][1]=c[i]-d[i]
合并转移(k=i+j)
f[x][k][0]=f[x][i][0]+f[y][j][0]
f[x][k][1]=f[x][i][1]+min(f[y][j][0],f[y][j][1])
实现时会算重(因为是01背包)
法1:枚举和\(k\),逆着扫\(k\),再枚举i或j中的一个
法2:枚举\(i\),逆着扫\(i\),再枚举\(j\)
solution
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;
const int M=5e3+7;
typedef long long LL;
inline int rd(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return f?x:-x;
}
struct vec{
int g[M],te;
struct edge{
int y,nxt;
edge(int _y=0,int _nxt=0){y=_y,nxt=_nxt;}
}e[M<<1];
vec(){memset(g,0,sizeof g);te=0;}
inline void push(int x,int y){e[++te]=edge(y,g[x]);g[x]=te;}
inline void push2(int x,int y){push(x,y);push(y,x);}
inline int& operator () (int x){return g[x];}
inline edge& operator [] (int x){return e[x];}
}e;
int n,sz[M];
LL lim,c[M],d[M];
LL f[M][M][2];
void dfs(int x,int fa){
int i,j,k,p,y;
sz[x]=1;
f[x][0][0]=0;
f[x][1][0]=c[x];
f[x][1][1]=c[x]-d[x];
for(p=e(x);p;p=e[p].nxt)
if((y=e[p].y)!=fa){
dfs(y,x);
for(k=sz[x]+sz[y];k>=0;k--)
for(j=0;j<=sz[y];j++) if((i=k-j)<=sz[x]){
f[x][k][0]=min(f[x][k][0],f[x][i][0]+f[y][j][0]);
f[x][k][1]=min(f[x][k][1],min(f[x][i][1]+f[y][j][0],f[x][i][1]+f[y][j][1]));
}
sz[x]+=sz[y];
}
}
int main(){
int i,x;
n=rd(); lim=rd();
for(i=1;i<=n;i++){
c[i]=rd(), d[i]=rd();
if(i>1) e.push(rd(),i);
}
memset(f,0x3f,sizeof f);
dfs(1,0);
int ans=0;
for(i=0;i<=n;i++) if(min(f[1][i][0],f[1][i][1])<=lim) ans=i;
printf("%d\n",ans);
return 0;
}
cf 816E Karen and Supermarket的更多相关文章
- 816E. Karen and Supermarket 树形DP
LINK 题意:给出n个商品,除第一个商品外,所有商品可以选择使用优惠券,但要求其前驱商品已被购买,问消费k以下能买几个不同的商品 思路:题意很明显就是树形DP.对于一个商品有三种选择,买且使用优惠券 ...
- CodeForces 816E Karen and Supermarket ——(树形DP)
题意:有n件商品,每件商品都最多只能被买一次,且有一个原价和一个如果使用优惠券以后可以减少的价格,同时,除了第一件商品以外每件商品都有一个xi属性,表示买这个商品时如果要使用优惠券必须已经使用了xi的 ...
- 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 ...
随机推荐
- c++中的结构化语句 判断语句if 分支语句switch 循环语句 while 和 do while 循环语句for的使用
作业1: 使用if语句,根据1~7的数字,输出今天是星期几?的程序. 方法一,直接使用单独的if语句 #include <iostream> using namespace std; in ...
- Angular2 Service获取json数据
在Angular2框架下一般交互解析json是要用到Service的,其实除了Service还是很多的,今天先写个最简单的前后端数据交互 嗯~~ 首先我先在app包下直接创建Service 好了 这里 ...
- STL笔记(に)--vector容器
Vector 1.可变长的动态数组 2.需包含头文件#include<vector> (当然,如果用了万能头文件#include<bits/stdc++.h>则可忽略) 3.支 ...
- 第2 章Python 语言基础
必背必记 1.转义字符 Python 中的字符串还支持转义字符.所谓转义字符是指使用反斜杠“\”对一些特殊字符进行转义. \ 续行符 \n 换行符 \0 空 \t 水平制表符,用于横向跳到下一制表 ...
- 分享自己写的基于Dapper的轻量级ORM框架~
1.说明 本项目是一个使用.NET Standard 2.0开发的,基于 Dapper 的轻量级 ORM 框架,包含基本的CRUD以及根据表达式进行一些操作的方法,目前只针对单表,不包含多表连接操作. ...
- 基于django的个人博客网站建立(三)
基于django的个人博客网站建立(三) 前言 网站效果可点击这里访问 今天主要完成的是文章在页面的显示以及评论,留言 具体内容 首先我希望主页面是显示我的所有文章,于是在主页面的视图函数中返回了所有 ...
- 怎么选取训练神经网络时的Batch size?
怎么选取训练神经网络时的Batch size? - 知乎 https://www.zhihu.com/question/61607442 深度学习中的batch的大小对学习效果有何影响? - 知乎 h ...
- python3.7 装饰器
#!/usr/bin/env python __author__ = "lrtao2010" #python3.7 装饰器 #装饰器 ''' 定义:本质就是一个函数,作用是为其他函 ...
- python之格式化
python有两种方式可以格式化一种是用%s,一种使用format(2.6)进入的,从下面的代码可以看出,效果差不多. name = 'edward' age = 27 print("My ...
- c++ string vector类
//string对象的初始化 #include <iostream> #include <string> //typedef std::basic_string<char ...