多重背包是某个物品可以选择多次,要把对物品数的枚举放在对w枚举外面
分组背包是某组的物品只能选一个,要把对每组物品的枚举放在对w枚举内侧
依赖背包是多层的分组背包,利用树形结构建立依赖关系,每个结点都可以看做分组背包来做
/* dp[i][j]表示以点i为根,取j个点的状态 */ #include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; #define maxn 300 vector<int>G[maxn]; int n,m,dp[maxn][maxn],v[maxn]; void dfs(int fa){ for(int i=0;i<G[fa].size();i++){ int ch=G[fa][i]; if(G[ch].size()>0)dfs(ch); }
for(int i=0;i<G[fa].size();i++){//这就是一个分组背包 int ch=G[fa][i]; for(int j=m;j>=1;j--) for(int k=1;k<=j;k++) dp[fa][j]=max(dp[fa][j],dp[fa][k]+dp[ch][j-k]); } } int main(){ while(scanf("%d%d",&n,&m),n){ int a,b; m++;//多加一个虚点 memset(dp,0,sizeof dp); for(int i=0;i<=n;i++)G[i].clear(); for(int i=1;i<=n;i++){ scanf("%d%d",&a,&b); v[i]=b;G[a].push_back(i); for(int j=1;j<=m;j++) dp[i][j]=b; } dfs(0); printf("%d ",dp[0][m]); } }