Karen and Supermarket題解

Karen and Supermarket題解

每一個物品只對一個物品有依賴性,因此是一顆樹的結構;
可是顯然,\(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;
}
相關文章
相關標籤/搜索