每一個物品只對一個物品有依賴性,因此是一顆樹的結構;
可是顯然,\(b\)的範圍是\(1<=b<=1e9\)存不下,
不能設\(f[x][i][2]:\)爲以x爲節點,i爲容量用/不用優惠券的最大物品個數(不能用揹包)。
可是咱們能夠換一換嘛:
設\(f[x][i][2]\)爲以x爲節點,選i個物品用/不用優惠券的最小費用。
若x使用,則兒子能夠選擇用,也能夠不用;
x不用,兒子也不能用;
沒什麼好說的。c++
#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; }