1 条题解
-
5
本蒟蒻实在没有想到怎么用背包去做........那 就只好写树形dp了 直接上代码
#include<bits/stdc++.h> using namespace std; int n,m,w[201],c[201],x,f[201][40001]; int head[200];//链式前向星头结点(第一条边) int k,ans; struct edge{ int to;//这条边到达的点 int next;//下一条边的编号 }e[201]; inline void add(int u,int v){//建树(双向边) e[++k].to=v; e[k].next=head[u]; head[u]=k; e[++k].to=u; e[k].next=head[v]; head[v]=k; } void dfs(int u/*当前节点*/,int t/*当前容量*/,int fat/*父亲节点*/){ if(t<=0) return ;//存不下了 for(int i=head[u];i;i=e[i].next)/*遍历这棵树*/{ int v=e[i].to; if(v==fat) continue;//如果是父节点直接跳过 for(int k=n-w[v];k>=0;k--){ f[v][k]=f[u][k]+c[v];//如果选子树必须选这个节点 } dfs(v,t-w[v],u);//继续递归 for(int k=n;k>=w[v];k--){ f[u][k]=max(f[u][k],f[v][k-w[v]]);//01背包选或不选 } } return; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d%d",&w[i],&c[i],&x); c[i]*=w[i]; add(i,x); } dfs(0,n,-1);//0为根节点,递归dp for(int i=0;i<=n;i++){ ans=max(ans,f[0][i]); } printf("%d",ans); return 0; }
- 1
信息
- ID
- 152
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 8
- 标签
- 递交数
- 30
- 已通过
- 7
- 上传者