标签:ios 树形dp vector ica 大致 att tor oct std
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 9128 | Accepted: 5250 |
Description
Input
Output
Sample Input
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0
Sample Output
5
Source
大致题意:
某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大。
思路:
任何一个点的取舍可以看作一种决策,那么状态就是在某个点取的时候或者不取的时候,以他为根的子树能有的最大活跃总值。分别可以用f[i,1]和f[i,0]表示第i个人来和不来。
上司来,下属不来
当i来的时候,dp[i][1] += dp[j][0];//j为i的下属
上司不来,下属来或不来
当i不来的时候,dp[i][0] +=max(dp[j][1],dp[j][0]);//j为i的下属
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdio> 6 #include<cstdlib> 7 #include<cstring> 8 #include<string> 9 10 using namespace std; 11 12 #define maxn 6005 13 14 int n; 15 int dp[maxn][2],father[maxn];//dp[i][0]0表示不去,dp[i][1]1表示去了 16 bool visited[maxn]; 17 18 void tree_dp(int node) 19 { 20 int i; 21 visited[node] = 1; 22 for(i=1; i<=n; i++) //找1到n中找node节点的下属 23 { 24 if(!visited[i]&&father[i] == node)//i为下属 25 { 26 tree_dp(i);//递归调用孩子结点,从叶子结点开始dp 27 //关键 28 dp[node][1] += dp[i][0];//上司来,下属不来 29 dp[node][0] +=max(dp[i][1],dp[i][0]);//上司不来,下属来、不来 30 } 31 } 32 } 33 34 int main() 35 { 36 int i; 37 int f,c,root; 38 while(scanf("%d",&n)!=EOF) 39 { 40 memset(dp,0,sizeof(dp)); 41 memset(father,0,sizeof(father)); 42 memset(visited,0,sizeof(visited)); 43 for(i=1; i<=n; i++) 44 { 45 scanf("%d",&dp[i][1]); 46 } 47 root = 0;//记录父结点 48 bool beg = 1; 49 while (scanf("%d %d",&c,&f),c||f) 50 { 51 //c的老爸是f 52 father[c] = f; 53 //儿子是跟节点 或者这条边是第一条边 54 //父亲做根节点 55 if( root == c || beg ) 56 { 57 root = f; 58 } 59 } 60 //循环寻找根节点 61 while(father[root])//查找父结点 62 root=father[root]; 63 //从根节点开始树形dp 64 tree_dp(root); 65 //取最大的上司去或者不去中的大值 66 int imax=max(dp[root][0],dp[root][1]); 67 printf("%d\n",imax); 68 } 69 return 0; 70 71 }
poj2342 Anniversary party (树形dp)
标签:ios 树形dp vector ica 大致 att tor oct std
原文地址:http://www.cnblogs.com/Renyi-Fan/p/7421127.html