Question Link: Http://acm.zju.edu.cn/onlinejudge/showProblem.do? Problemcode = 3626.
Theme: The vertex in the tree. Each side has a cost, and the end must return to the starting point. Given the budget M, ask the maximum value.
Solutions:
First of all, pay attention to this question to return to the starting point. Because of the special structure of the tree (each node has only one parent), that is, to return to the beginning,
The overhead is twice. So first M/= 2.
Then there is the solution of the tree-shaped backpack. The cost of this question is on the edge, so the for statement is changed to the following:
For (M... j... 0)
For (0... k... j-e.cost)
DP [I] [J] = max (DP [I] [J], DP [I] [j-k-e.cost] + dp [T] [k]);
The main change of the For Loop is 0, that is to say, the overhead of some points can be 0 (calculated by the father ).
So the initialization should also be changed to: For (INT I = 0; I <= m; I ++) DP [root] [I] = W [root];
The main change of the DP equation is DP [I] [J-K]-> DP [I] [j-k-e.cost]. Here e is subtracted. cost is used to prevent cost from repeated computation.
You may wish to set K = j-e.cost, you will find in the calculation DP [I] [0], this is why the cost = 0 state.
#include "cstdio"#include "iostream"#include "cstring"using namespace std;#define maxn 300struct Edge{ int to,next,c;}e[maxn*2];int w[maxn],num[maxn],dp[maxn][maxn],head[maxn],tol;int n,m,k,u,v,c;void addedge(int u,int v,int c){ e[tol].to=v; e[tol].next=head[u]; e[tol].c=c; head[u]=tol++;}void dfs(int root,int pre){ for(int i=0;i<=m;i++) dp[root][i]=w[root]; int i=root; for(int a=head[root];a!=-1;a=e[a].next) { int t=e[a].to; if(t==pre) continue; dfs(t,root); for(int j=m;j>=0;j--) for(int k=0;k<=j-e[a].c;k++) dp[i][j]=max(dp[i][j],dp[i][j-k-e[a].c]+dp[t][k]); }}int main(){ //freopen("in.txt","r",stdin); while(~scanf("%d",&n)) { memset(head,-1,sizeof(head)); memset(dp,0,sizeof(dp)); tol=0; for(int i=1;i<=n;i++) scanf("%d",&w[i]); for(int i=1;i<n;i++) { scanf("%d%d%d",&u,&v,&c); addedge(u,v,c); addedge(v,u,c); } scanf("%d%d",&k,&m); m/=2; dfs(k,k); printf("%d\n",dp[k][m]); }}
2875311 |
Neopenx |
Zoj |
3626 |
Accepted |
636 |
0 |
C ++ (G ++ 4.4.5) |
1174 |
09:13:13 |
Zoj 3626 (tree DP + backpack + side cost)