标签:优惠券 不用 head ++ super 不能 结构 name 背包
每个物品只对一个物品有依赖性,所以是一颗树的结构;
但是显然,\(b\)的范围是\(1<=b<=1e9\)存不下,
不能设\(f[x][i][2]:\)为以x为节点,i为容量用/不用优惠券的最大物品个数(不能用背包)。
但是我们可以换一换嘛:
设\(f[x][i][2]\)为以x为节点,选i个物品用/不用优惠券的最小费用。
若x使用,则儿子可以选择用,也可以不用;
x不用,儿子也不能用;
没什么好说的。
#include<bits/stdc++.h>
using namespace std;
const int N=5006;
int n,t,w,siz[N],c[N],d[N],cnt=0,head[N],f[N][N][2];
struct edge{int nxt,to;}e[N<<1];
inline void add(int u,int v){e[++cnt].nxt=head[u],e[cnt].to=v,head[u]=cnt;}
inline int read(){
int T=0,F=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
return F*T;
}
void dfs(int x){
siz[x]=1,f[x][0][0]=0,f[x][1][0]=c[x],f[x][1][1]=c[x]-d[x];
for(int i=head[x];i;i=e[i].nxt) {
dfs(e[i].to);
for(int j=siz[x];j>=0;--j)
for(int k=siz[e[i].to];k>=0;--k)
f[x][j+k][0]=min(f[x][j+k][0],f[x][j][0]+f[e[i].to][k][0]);
for(int j=siz[x];j>=1;--j)
for(int k=siz[e[i].to];k>=0;--k)
f[x][j+k][1]=min(f[x][j+k][1],f[x][j][1]+min(f[e[i].to][k][0],f[e[i].to][k][1]));
siz[x]+=siz[e[i].to];
}
}
int main(){
n=read(),w=read(),c[1]=read(),d[1]=read(),memset(f,0x3f,sizeof(f));
for(int i=2;i<=n;++i) c[i]=read(),d[i]=read(),t=read(),add(t,i);
dfs(1);
for(int i=n;i>=1;--i) if(w>=f[1][i][0]||w>=f[1][i][1]){printf("%d\n",i); return 0;}
printf("0\n");
return 0;
}
标签:优惠券 不用 head ++ super 不能 结构 name 背包
原文地址:https://www.cnblogs.com/ljk123-de-bo-ke/p/11729553.html