Karen and Supermarket题解

Karen and Supermarket题解

每个物品只对一个物品有依赖性,所以是一颗树的结构;
但是显然,\(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;
}
posted @ 2019-10-24 08:11  lsoi_ljk123  阅读(97)  评论(0编辑  收藏  举报