Topic links
BZOJ1017: [JSOI2008] Warcraft Map DOTR
Exercises
Set Dp[i][j][k] denotes a subtree in the root of I, with J I nodes used for and into the upper layer, the maximum benefit of the K is spent
Enumerate the synthetic L-nodes and make some other power in the subtree with the rest of the money
G[I][J] represents the maximum benefit that J can get for the former I subtrees tree of the current subtree
Get g[i][j] = G[i-1][k] + dp[v][need[v] * L][j-k]///Note that the transfer is guaranteed to be able to synthesize the upper L
Dp[x][j][k] = max (G[totson][k]))
Final backpack Merge
Pay attention to the legal State transfer
Code
/* Set DP[I][J][K] denotes a subtree with I as the root, there are J I nodes used for and into the upper layer, the maximum benefit of the k is enumerated to synthesize l I node, and then use the remaining money in the subtree to make some other powerg[i][j] Represents the maximum gain for the former I subtrees tree of the current subtree by spending J to get g[i][j] = G[i-1][k] + dp[v][need[v] * L][j-k]///Note that this has been transferred to ensure that you can synthesize the upper L-dp[x][j][k] = max (g[to TSON][K])) Last Backpack merger note the legal State transfer */#include <bits/stdc++.h> using namespace std; inline int read () {int x = 0,f = 1; char C = GetChar (); while (C < ' 0 ' | | c > ' 9 ') {if (c = = '-') F = -1;c = GetChar ();} while (c <= ' 9 ' && C >= ' 0 ') x = x * ten + C-' 0 ', C = GetChar (); return x * F; } #define INF 1000000007 int n,m; const int MAXN = 87; const int MAXM = 2007; int LIMIT[MAXN],COST[MAXN],POWER[MAXN]; struct node {int v,next,w;} EDGE[20007]; int DEG[MAXN]; int DP[MAXN][MAXN * 2][MAXM]; int G[MAXN][MAXM]; int NUM,HEAD[MAXN << 1]; void Add_edge (int u,int v,int w) {edge[++ num].v = V;EDGE[NUM].W = w; edge[num].next = Head[u]; head[u] = num;} void DFS (int x) {if (!head[x]) {for (int i = 0;i <= limit[x];++ i) for (int j = 0;J <= i;++ J) dp[x][j][i * Cost[x]] = (i-j) * power[x]; return; } limit[x] = INF; for (int i = Head[x];i;i = edge[i].next) {int v = EDGE[I].V; DFS (v); LIMIT[X] = std::min (Limit[x],limit[v]/EDGE[I].W); COST[X] + = cost[v] * EDGE[I].W; } Limit[x] = Std::min (limit[x],m/cost[x]); memset (g,-0x3f3f3f3f,sizeof g); G[0][0] = 0; printf ("%d\n", g[1][1]); int tmp = 0,tot = 0; for (int l = limit[x];l >= 0;--l) {tot = 0,tmp = 0; for (int v,i = Head[x];i;i = edge[i].next) {tot + +; v = edge[i].v; TMP + = cost[v] * EDGE[I].W; for (int j = 0/*tmp*/;j <= m;++ j) for (int k = 0/*tmp*/;k <= j;++ k) g[tot][j] = std: : Max (G[tot][j],g[tot-1][k] + DP[V][EDGE[I].W * l][j-k]); } for (int i = 0;i <= l;++ i) for (int k = 0;k <= m;++ k) Dp[x][i][k] = Std::max (dp[x][i][k],g[tot ][K] + power[x] * (l-i)); }} int H[MAXN][MAXM]; int main () {memset (dp,-0x3f3f3f3f,sizeof DP); n = Read (), M = Read (); Char op[10]; for (int a,b,c,d,i = 1;i <= n;++ i) {power[i] = read (); scanf ("%s", op); if (op[0] = = ' A ') {b = read (); for (int j = 1;j <= b;++ j) {c = read (), d = Read (); Add_edge (I,C,D); DEG[C] + +; }} else {cost[i] = read (), limit[i] = read (); if (Cost[i]) limit[i] = Std::min (Limit[i],m/cost[i]); }} int tot = 0; for (int x = 1;x <= n;++ x) {if (!deg[x]) {DFS (x); Tot + +; for (int i = 0;i <= m;++ i) for (int j = 0;j <= i;++ j) {for (int k = 0;k <= li mit[x];++ k) {H[tot][i] = max (H[tot][i],h[tot-1][j] + dp[x][k][i-j]); }}}} int ans = 0; FoR (int i = 0;i <= m;++ i) ans = Std::max (ans,h[tot][i]); printf ("%d\n", ans);
bzoj1017: [JSOI2008] Warcraft map DOTR