树形DP

 


P1352 没有上司的舞会

题目描述

某大学有N个职员,编号为1~N。他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但是呢,如果某个职员的上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。

输入格式

第一行一个整数N。(1<=N<=6000)

接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)

接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。

最后一行输入0 0

输出格式

输出最大的快乐指数。

输入输出样例

输入 #1
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
输出 #1
5
 
  鬼畜的存表方式qwq。
 1 #include<bits/stdc++.h> 
 2 
 3 using namespace std;
 4 int f[2][6005];
 5 int n,x,y,ro;
 6 int fr[12005],ne[12005],fa[12005];
 7 void dp(int x)
 8 {
 9     for(int i=fr[x];i;i=ne[i])
10     {
11         dp(i);
12         f[1][x]=max(max(f[1][x],f[0][i]+f[1][x]),f[0][i]);
13         f[0][x]=max(max(f[0][x],f[1][i]+f[0][x]),max(f[0][i],f[1][i]));
14     }
15 }
16 int main()
17 {
18     cin>>n;
19     for(int i=1;i<=n;i++)
20     cin>>f[1][i];
21     for(int i=1;i<=n;i++)
22     {
23         cin>>x>>y;
24         fa[x]++;
25         ne[x]=fr[y];
26         fr[y]=x;
27     }
28     for(int i=1;i<=n;i++)
29     if(fa[i]==0)
30     {
31         ro=i;
32         break;
33     }
34     dp(ro);
35     cout<<max(f[1][ro],f[0][ro]);
36     return 0;
37 }
View Code

 


P1040 加分二叉树

题目描述

设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号。每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都有一个加分,任一棵子树subtreesubtree(也包含treetree本身)的加分计算方法如下:

subtree的左子树的加分× subtree的右子树的加分+subtree的根的分数。

若某个子树为空,规定其加分为1,叶子的加分就是叶节点本身的分数。不考虑它的空子树。

试求一棵符合中序遍历为(1,2,3,…,n)且加分最高的二叉树tree。要求输出;

(1)tree的最高加分

(2)tree的前序遍历

输入格式

1行:1个整数n(n<30),为节点个数。

2行:n个用空格隔开的整数,为每个节点的分数(分数<100)。

输出格式

1行:1个整数,为最高加分(Ans4,000,000,000)。

2行:n个用空格隔开的整数,为该树的前序遍历。

输入输出样例

输入 #1
5
5 7 1 2 10
输出 #1
145
3 1 2 4 5
 
  枚举哪个是根。
 1 #include<bits/stdc++.h>
 2 #define re register int
 3 #define LL long long 
 4 #define maxn 30+5
 5  
 6 using namespace std;
 7 LL f[maxn][maxn];
 8 int root[maxn][maxn];
 9 int n;
10 inline LL dp(int  l,int r)
11 {
12     if(f[l][r]) return f[l][r];
13     for(re k=l+1;k<=r-1;k++)
14     {
15         if(dp(l,k-1)*dp(k+1,r)+f[k][k]>f[l][r])
16         root[l][r]=k,f[l][r]=dp(l,k-1)*dp(k+1,r)+f[k][k];
17     } 
18     if(dp(l+1,r)+f[l][l]>f[l][r])
19     root[l][r]=l,f[l][r]=dp(l+1,r)+f[l][l];
20     if(dp(l+1,r)+f[l][l]>f[l][r])
21     root[l][r]=l,f[l][r]=dp(l+1,r)+f[l][l];
22     return f[l][r];
23 }
24 void print(int l,int r)
25 {
26     if(l==r) {
27     cout<<l<<' ';
28     return;
29     }
30     cout<<root[l][r]<<' ';
31     if(root[l][r]-1>=l) print(l,root[l][r]-1);
32     if(root[l][r]+1<=r)  print(root[l][r]+1,r);
33 }
34 int main()
35 {
36     ios::sync_with_stdio(false);
37     cin>>n;
38     for(re i=1;i<=n;i++)
39     cin>>f[i][i];
40     cout<<dp(1,n)<<endl;
41     print(1,n);
42 }
View Code

 

posted @ 2019-10-09 21:10  3200Phaethon  阅读(174)  评论(2编辑  收藏  举报