<span style="font-size:18px;">题意:有n个人,接下来n行是n个人的价值,再接下来n行给出l,k,k是l的上司,问有直接隶属关系不能同时出现的条件下 能达到的价值最大和 思路:树形dp 其实就是优化了的dfs ; 先找到根,再递归每个节点 使其作为根 并求出其当前最大的价值和,状态方程如下: 当i来的时候,dp[i][1] += dp[j][0];//j为i的下属 当i不来的时候,dp[i][0] +=max(dp[j][1],dp[j][0]);//j为i的下属 代码: #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <stdlib.h> #include <string.h> #include <iomanip> #define N 6010 #define INF 10000000 #define LL long long #define eps 10E-9 #define mem(a) memset(a,0,sizeof(a)) #define w(a) while(a) #define s(a) scanf("%d",&a) #define ss(a,b) scanf("%d%d",&a,&b) #define sss(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define MAXN 9999 #define MAXSIZE 10 #define DLEN 4 #define MAXN 9999 #define MAXSIZE 10 #define DLEN 4 using namespace std; int dp[N][2]; int vis[N],dad[N]; int n; void tree_dp(int node){ vis[node]=1; for(int i=1; i<=n; i++){ if(!vis[i] && dad[i]==node){ tree_dp(i); dp[node][1] += dp[i][0]; dp[node][0] += max(dp[i][0], dp[i][1]); } } } int main() { w(~s(n)){ mem(dp); mem(dad); mem(vis); for(int i=1; i<=n; i++){ s(dp[i][1]); } int e, c, root = 0; w(ss(e,c) && (e|c)){ dad[e] = c; if(root = e){ root = c; } } w(dad[root]){ root = dad[root]; } tree_dp(root); cout<<max(dp[root][0],dp[root][1])<<endl; } return 0; } </span>
poj 2342 树形dp
最新推荐文章于 2020-09-20 09:29:13 发布