hdu1520 (树形dp)

hdu1520 http://acm.hdu.edu.cn/showproblem.php?pid=1520

题意是给定一棵树,每个结点有一个价值,要我们选择任意个结点使得总价值最大,规则是如果父亲结点被选了,那么儿子结点不可以被选,但是儿子的儿子可以被选

本来学搜索的时候找到这题搜索题,然后用搜索做的

 1 #include <stdio.h>

 2 #include <string.h>

 3 #include <stdlib.h>

 4 #include <algorithm>

 5 #include <iostream>

 6 #include <queue>

 7 #include <stack>

 8 #include <vector>

 9 #include <map>

10 #include <set>

11 #include <string>

12 #include <math.h>

13 using namespace std;

14 typedef long long LL;                   

15 const int INF = 1<<30;

16 int val[6666];

17 int f[6666];

18 vector<int> g[6666];

19 int dfs(int u, bool flag)//flag标记父亲结点是不是取

20 {

21     int t,t2;

22     if(!flag)

23         t = val[u];

24     t2 = 0;

25     for(int i=0; i<g[u].size(); ++i)

26     {

27         int v = g[u][i];

28         if(!flag)

29         {

30             t += dfs(v,true);

31         }

32         t2 += dfs(v,false);

33     }

34     if(flag)

35         return t2;

36     return max(t,t2);

37 }

38 int main()

39 {

40     int n,i,x,y;

41     while(scanf("%d",&n)!=EOF)

42     {

43         

44         for(i=1; i<=n; ++i)

45         {

46             g[i].clear();

47             scanf("%d",&val[i]);

48             f[i] = -1;

49         }

50         while(scanf("%d%d",&x,&y),x)

51         {

52             g[y].push_back(x);

53             f[x] = y;

54         }

55         x = 1;

56         while(f[x]!=-1)

57             x = f[x];

58         printf("%d\n",dfs(x,false));

59     }

60     return 0;

61 }
View Code

 

但是学树形dp的时候又找到这道题,然后用树形dp重新做了一次,提高上去,运行的时间变少了

dp[u][1] 表示选择结点u可以获得的最大价值

dp[u][0]表示不选择结点u可以获得的最大价值

状态转移方程是 dp[u][1] = max( dp[u][1], dp[u][1]+dp[v][0] ); dp[u][0] = max( dp[u][0],max(dp[u][0]+dp[v][1], dp[u][0]+dp[v][0]) );

 

 1 #include <stdio.h>

 2 #include <string.h>

 3 #include <stdlib.h>

 4 #include <algorithm>

 5 #include <iostream>

 6 #include <queue>

 7 #include <stack>

 8 #include <vector>

 9 #include <map>

10 #include <set>

11 #include <string>

12 #include <math.h>

13 using namespace std;

14 typedef long long LL;                   

15 const int INF = 1<<30;

16 const int N = 6000 + 10;

17 int val[N];

18 int dp[N][2];//dp[u][1]表示选这个结点的最大值, dp[u][0] 表示不选这个结点的最大值

19 struct Edge

20 {

21     int v,next;

22 }g[N<<1];

23 int head[N],e;

24 

25 void dfs(int u, int fa)

26 {

27     dp[u][1] = val[u];

28     dp[u][0] = 0;

29     for(int i=head[u]; i!=-1; i=g[i].next)

30     {

31         int v = g[i].v;

32         if(v==fa) continue;

33         dfs(v,u);

34         dp[u][1] = max(dp[u][1],dp[u][1]+dp[v][0]);

35         dp[u][0] = max(dp[u][0],max(dp[u][0]+dp[v][1],dp[u][0]+dp[v][0] ));

36         

37         //dp[u][1] += dp[v][0];

38         //dp[u][0] += dp[v][1];

39     }

40 }

41 void init(int n)

42 {

43     for(int i=1; i<=n; ++i)

44         head[i] = -1;

45     e = 0;

46 }

47 void addEdge(int u, int v)

48 {

49     g[e].v = v;

50     g[e].next = head[u];

51     head[u] = e++;

52 }

53 

54 int main()

55 {

56     int n,i,a,b;

57     while(scanf("%d",&n)!=EOF)

58     {

59         init(n);

60         for(i=1; i<=n; ++i)

61             scanf("%d",&val[i]);

62         while(scanf("%d%d",&a,&b),a)

63         {

64             addEdge(a,b);

65             addEdge(b,a);

66             //g[a].push_back(b);

67             //g[b].push_back(a);

68         }

69         dfs(1,-1);

70         printf("%d\n",max(dp[1][0],dp[1][1]));

71     }

72     return 0;

73 }
View Code

 

最近老发现用vector建图提交老师runtime error,

你可能感兴趣的:(HDU)