The dish recommended "water problem" abused me a day t ... (Vegetables are good qwq~
Obviously is a score plan problem, two points answer calculate P[i]-mid*s[i] After running on the tree depends on the backpack, choose K Maximum value if the >0 explanation also has more excellent solution.
The first contact tree-dependent backpack, so the previous more than 10 FA WA and tle are all wrong, I still naive t t
The general practice of tree-dependent backpacks is to DFS sequence DP, set F[I][J] as the DFS order I point, has selected the maximum value of J points, Nxt[i] The next subtree of I, the DFS sequence is:
F[NXT[I]][J]=F[I][J]
F[i+1][j+1]=f[i][j]+w[i]
Note that tree-dependent backpacks are best used with brush-table methods, because if the cost of the requirement must be k and the weights have negative values, the use of the fill-in method may result in a transfer from the legal state.
#include <iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<algorithm>using namespacestd;Const intmaxn=2510, inf=1e9;structpoi{intToo,pre;} E[MAXN];intn,k,x,tot,cnt,mx;intDFN[MAXN],NXT[MAXN],LAST[MAXN],S[MAXN],P[MAXN];DoubleF[maxn][maxn],w[maxn];inlinevoidReadint&k) { intf=1; k=0;CharC=GetChar (); while(c<'0'|| C>'9') c=='-'&& (f=-1), c=GetChar (); while(c<='9'&&c>='0') k=k*Ten+c-'0', c=GetChar (); K*=F;}voidAddintXintY) {e[++tot].too=y;e[tot].pre=last[x];last[x]=tot;}voidDfsintx) {Dfn[x]=cnt++; for(intI=last[x];i;i=e[i].pre) DFS (E[i].too); NXT[DFN[X]]=CNT;}intMain () {read (k); Read (n); for(intI=1; i<=n;i++) read (S[i]), read (P[i]), read (x), add (x,i), mx=Max (mx,p[i]); DFS (0); DoubleL=0, r=1e4; while(r-l>1e-5) { DoubleMid= (L+R)/2; for(intI=1; i<=n;i++) w[dfn[i]]=1.0*p[i]-mid*S[i]; for(intI=1; i<=n+1; i++) for(intj=0; j<=k+1; j + +) f[i][j]=-inf; for(intI=0; i<=n;i++) for(intj=0; J<=min (i,k+1); J + +) { if(F[i][j]>f[nxt[i]][j]) f[nxt[i]][j]=F[i][j]; if(f[i][j]+w[i]>f[i+1][j+1]) f[i+1][j+1]=f[i][j]+W[i]; } if(f[n+1][k+1]>1e-5) L=mid;ElseR=mid; } printf ("%.3lf\n", L);}
View Code
The second approach can only be used at the cost of picking points, directly in the tree to do the backpack, but after each child node after the backpack to the size of the node is added to the parent node, this complexity is O (n^2).
#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>using namespacestd;Const intmaxn=2510;Doubleeps=1e-5, inf=1e12;structpoi{intToo,pre;} E[MAXN];intn,k,x,tot,sum;intP[MAXN],S[MAXN],SIZE[MAXN],LAST[MAXN];DoubleF[MAXN][MAXN],W[MAXN],G[MAXN];voidReadint&k) { intf=1; k=0;CharC=GetChar (); while(c<'0'|| C>'9') c=='-'&& (f=-1), c=GetChar (); while(c<='9'&&c>='0') k=k*Ten+c-'0', c=GetChar (); K*=F;}voidAddintXintY) {e[++tot].too=y;e[tot].pre=last[x];last[x]=tot;}voidDfsintx) {Size[x]=1; f[x][1]=W[x]; for(intI=last[x];i;i=e[i].pre) {DFS (E[i].too); for(intj=0; j<=size[x]+size[e[i].too];j++) g[j]=F[x][j]; for(intj=1; j<=size[x];j++) for(intk=1; k<=size[e[i].too];k++) G[j+k]=max (g[j+k],f[x][j]+F[e[i].too][k]); SIZE[X]+=Size[e[i].too]; for(intj=1; j<=size[x];j++) f[x][j]=G[j]; }} intMain () {read (k); Read (n); for(intI=1; i<=n;i++Read ( s[i]), read (P[i]), read (x), add (x,i); DoubleL=0, r=1e4; while(r-l>EPS) { DoubleMid= (L+R)/2; for(intI=1; i<=n;i++) w[i]=1.0*p[i]-mid*S[i]; for(intI=0; i<=n;i++) for(intj=1; j<=k+1; j + +) f[i][j]=-inf; DFS (0);if(f[0][k+1]>eps) L=mid;ElseR=mid; } printf ("%.3lf\n", L);}
View Code
bzoj4753: [Jsoi2016] Best Group (score plan + Tree dependent backpack)