Some bastion hosts need to conquer another bastion host, form a forest, conquer up to M bastion hosts, and seek the greatest value of the treasures.
1. Make 0 root to form a forest tree;
2. Calculate the greatest value of the treasure that can be obtained from K bastion hosts on the current node using a backpack. However, note that the same root node cannot be placed into a backpack successively, otherwise, for example, if one node selects two or three, five are selected, that is, some nodes are repeated. Therefore, we need to put all K types in order in the J lattice of back, j --;
#include<iostream>#include<string.h>#include<stdio.h>#include<vector>using namespace std;const int maxa = 205;int dp[maxa][maxa];int back[maxa][maxa];int vis[maxa][maxa];int v[maxa];vector<int> edge[maxa];int numb[maxa];int dfs(int x, int num ){//printf("%d %d\n", x, num); if(vis[x][num] || num == 0) return dp[x][num]; memset(back[x], 0, sizeof(back[x])); for(int i = 0; i < edge[x].size(); i ++){ int k = edge[x][i];//printf("%d ", k); int last = -1; for(int h = num-1; h >= 1; h--){ for(int j = 1; j <= h && j <= numb[k]; j++){ int a = dfs(k, j); back[x][h] = max(back[x][h], back[x][h-j] + a);//printf("%d ", back[h]); }//puts(""); } } vis[x][num] = 1; return dp[x][num] = back[x][num-1]+v[x];}int dfs1(int x){ int sum = 0; for(int i = 0; i < edge[x].size(); i++){ int k = edge[x][i]; sum += dfs1(k); } return numb[x] = sum +1;}int main(){int n, m; //freopen("in.cpp", "r", stdin); while(scanf("%d%d", &n, &m), n+m){ memset(vis, 0, sizeof(vis)); for(int i =0; i <= n; i++) edge[i].clear(); for(int i =1; i <= n; i++){ int a, b; scanf("%d%d", &a, &b); v[i] = b; edge[a].push_back(i); } dfs1(0); memset(dp, 0, sizeof(dp)); printf("%d\n", dfs(0, m+1)); /* for(int i = 0; i <= n; i++){ printf("*%d ", numb[i]); }*/ }}
View code
Tree-like DP hdu1561