洛谷题面传送门 & Atcoder 题面传送门

由于再过 1h 就是 NOI 笔试了所以题解写得会略有点简略。

考虑差分,记 \(b_i=c_i-c_{fa_i}\),那么根据题意有 \(b_i\le d,i=2,3,4,\cdots,n\),而 \(b_1\) 则没有任何约束条件。而如果我们令某个 \(b_i\) 加 \(1\),其余 \(b_i\) 均不变,那对应到原 \(c\) 序列上的操作效果就是 \(i\) 子树内的 \(c_j\) 加 \(1\),其余 \(c_j\) 不变,因此预处理出 \(i\) 子树大小 \(siz_i\) 以及 \(i\) 子树内所有 \(m_j\) 之和 \(w_i\),问题就转化为:有 \(n\) 类物品,第 \(i\) 类代价为 \(w_i\),价值为 \(siz_i\),第 \(2,3,4,\cdots,n\) 类物品有 \(d\) 个,第 \(1\) 类物品有无限个,求用不超过 \(X\) 的代价买到的物品的最大价值和。

一眼多重背包,不过此题数据范围高达 \(10^9\),直接稳了(指稳 TLE+MLE)。不过考虑一个错误的贪心,将所有物品按性价比 \(\dfrac{w_i}{siz_i}\) 从小到大排序然后贪心地取,每次能多取就多取,不过这个贪心显然是假的,反例随便举。不过这个贪心给了我们一点启发:对于两个满足 \(\dfrac{w_i}{siz_i}<\dfrac{w_j}{siz_j}\) 的物品 \(i,j\),如果目前 \(i\) 还能够再多取 \(siz_j\) 个,并且 \(j\) 目前取的个数多余 \(siz_i\) 个,那么我们完全可以让 \(j\) 少取 \(siz_i\) 个,\(i\) 多取 \(siz_j\) 个,这样肯定比原方案更优,也就是说我们钦定每个物品前 \(n\) 个中取了多少个,钦定完之后肯定就优先取 \(\dfrac{w_i}{siz_i}\) 小的物品更优了。

因此考虑将所有物品先拿 \(\min(n,d)\) 个出来多重背包,即记 \(f_i\) 表示最少需要多少的代价才能够获得 \(i\) 的收益,剩余部分贪心即可,多重背包可以通过二进制分组/单调队列优化,复杂度 \(\mathcal O(n^4\log n)/\mathcal O(n^4)\),本人使用的二进制分组。

const int MAXN=50;
const int MAXV=1.25e5;
const int MAXI=350;
int n,m,d,siz[MAXN+5],ord[MAXN+5];ll w[MAXN+5];
int hd[MAXN+5],to[MAXN+5],nxt[MAXN+5],ec=0;
void adde(int u,int v){to[++ec]=v;nxt[ec]=hd[u];hd[u]=ec;}
void dfs(int x){
siz[x]=1;
for(int e=hd[x];e;e=nxt[e]){
int y=to[e];dfs(y);
siz[x]+=siz[y];w[x]+=w[y];
}
}
bool cmp(int x,int y){return 1ll*w[x]*siz[y]<1ll*w[y]*siz[x];}
ll dp[MAXV+5],W[MAXI+5];
int V[MAXI+5],item_n=0,lim[MAXN+5];
int main(){
scanf("%d%d%d%lld",&n,&m,&d,&w[1]);
for(int i=2,f;i<=n;i++) scanf("%lld%d",&w[i],&f),adde(f,i);
dfs(1);for(int i=1;i<=n;i++) ord[i]=i;sort(ord+1,ord+n+1,cmp);
int mx=0;memset(dp,63,sizeof(dp));dp[0]=0;
for(int i=1;i<=n;i++){
int up=min((ord[i]==1)?0x3f3f3f3f:d,n);
mx+=up*siz[ord[i]];
int k=31-__builtin_clz(up);
for(int j=0;j<k;j++){
W[++item_n]=w[ord[i]]<<j;
V[item_n]=siz[ord[i]]<<j;
} W[++item_n]=w[ord[i]]*(up-(1<<k)+1);
V[item_n]=siz[ord[i]]*(up-(1<<k)+1);
lim[ord[i]]=((ord[i]==1)?0x3f3f3f3f:d)-up;
// printf("%d %d\n",ord[i],lim[ord[i]]);
} int ans=0;
for(int i=1;i<=item_n;i++) for(int j=mx;j>=V[i];j--)
chkmin(dp[j],dp[j-V[i]]+W[i]);
for(int i=0;i<=mx;i++) if(dp[i]<=m){
int lft=m-dp[i],sum=i;//printf("%d %d %d\n",i,lft,sum);
for(int j=1;j<=n;j++){
int can=min((int)(lft/w[ord[j]]),lim[ord[j]]);
// printf("%d\n",can);
sum+=can*siz[ord[j]];lft-=can*w[ord[j]];
} chkmax(ans,sum);
} printf("%d\n",ans);
return 0;
}

Atcoder Regular Contest 096 D - Sweet Alchemy(贪心+多重背包)的更多相关文章

  1. AtCoder Regular Contest 096

    AtCoder Regular Contest 096 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个 ...

  2. [AtCoder Regular Contest 096 E] Everything on It 解题报告 (第二类斯特林数+容斥原理)

    题目链接:https://arc096.contest.atcoder.jp/tasks/arc096_c Time limit : 4sec / Memory limit : 512MB Score ...

  3. Atcoder Regular Contest 096 C - Everything on It(组合数学)

    Atcoder 题面传送门 & 洛谷题面传送门 简单题,由于这场 arc 的 F 是 jxd 作业而我不会做,所以只好来把这场的 E 水掉了. 我们记 \(f(i)\) 为钦定 \(i\) 个 ...

  4. AtCoder Regular Contest 096 D - Static Sushi(线性dp)

    Problem Statement "Teishi-zushi", a Japanese restaurant, is a plain restaurant with only o ...

  5. AtCoder Regular Contest 098

    AtCoder Regular Contest 098 C - Attention 题意 给定一个只包含"E","W"字符串,可以花一的花费使他们互相转换.选定 ...

  6. AtCoder Regular Contest 061

    AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...

  7. AtCoder Regular Contest 094 (ARC094) CDE题解

    原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...

  8. AtCoder Regular Contest 092

    AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...

  9. AtCoder Regular Contest 093

    AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...

随机推荐

  1. HCNP Routing&Switching之BGP路由宣告

    前文我们了解了BGP报文结构.类型以及邻居状态相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15422924.html:今天我们来聊一聊BGP路由宣告 ...

  2. 【UE4 C++】 射线检测 LineTrace 及 BoxTrace、SphereTrace、CapsuleTrace API

    World.h 库里的 Trace API Trace模式 TraceSingle 单个结果 TraceMulti 多个结果 Trace 的检测依据 ByChanne ByObjectType ByP ...

  3. 测试小姐姐问我 gRPC 怎么用,我直接把这篇文章甩给了她

    原文链接: 测试小姐姐问我 gRPC 怎么用,我直接把这篇文章甩给了她 上篇文章 gRPC,爆赞 直接爆了,内容主要包括:简单的 gRPC 服务,流处理模式,验证器,Token 认证和证书认证. 在多 ...

  4. The WebSocket session [0] has been closed and no method (apart from close()) may be called on a closed session-ConcurrentHashMap使用在webSocket中采的坑

    一.问题由来 现在开发的一个项目中使用webSocket这个技术和Unity客户端程序进行联动操作,因为socket连接相对来说比http请求连接更加的快速,而且是 一个长链接,方便于这个项目进行其他 ...

  5. 运维常用python库&模块

    sutil:是一个跨平台库(https://github.com/giampaolo/psutil)能够实现获取系统运行的进程和系统利用率(内存,CPU,磁盘,网络等),主要用于系统监控,分析和系统资 ...

  6. Noip模拟33垫底反思 2021.8.8

    T1 Hunter 考场上没写$%p$挂了25分.也是很牛皮,以后打完过了样例一定要检查 因为样例太小了......很容易忘记%%%% 正解随便手模就出来了. 1 #include<bits/s ...

  7. Java 将Excel转为et和ett格式

    以.et结尾的文件格式是属于金山办公软件WPS Office中的电子表格文件,.ett是一种模板文件格式.除了通过WPS软件可以创建该格式的电子表格外,也可以通过格式转换的方法来获得,如将Micros ...

  8. Verdi UVM Debug Mode 简单使用

    转载:Verdi UVM Debug Mode 简单使用_Holden_Liu的博客-CSDN博客 文档与源码: User Guide: UVMDebugUserGuide.pdf  in $VERD ...

  9. 字典树(Trie)

    终于学会字典树了,真开心(然后就滚过来写总结了). 首先,字典树到底是个什么东西呢?请看下面这段话: 字典树,常被用来保存与查找大量的字符串,它利用了字符串之间的公共前缀来节约时间,但它的空间花费较大 ...

  10. hdu 5101 Select (二分+单调)

    题意: 多多有一个智商值K. 有n个班级,第i个班级有mi个人.智商分别是v1,v2,.....vm. 多多要从这些人中选出两人.要求两人智商和大于K,并且两人不同班.问总共有多少种方案. 数据范围: ...