zoukankan      html  css  js  c++  java
  • 树形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
  • 相关阅读:
    codevs 4511 信息传递(NOIP2015 day1 T2)
    caption标签,为表格添加标题和摘要
    用css样式,为表格加入边框
    table标签,认识网页上的表格
    认识div在排版中的作用
    使用ol,添加图书销售排行榜
    使用ul添加列表
    使用<pre>标签为你的网页加入大段代码
    想加入一行代码吗?使用<code>标签
    <address>标签,为网页加入地址信息
  • 原文地址:https://www.cnblogs.com/3200Pheathon/p/11644396.html
Copyright © 2011-2022 走看看