zoukankan      html  css  js  c++  java
  • [题解] codevs 1486 愚蠢的矿工

    http://codevs.cn/problem/1486/

    我们比较熟悉二叉树,题目中给出的是一棵多叉树,我们需要将这可二叉树改造成二叉树。

    二叉树可以为这样的:

    父亲结点左边储存儿子,右边储存兄弟。

    有两种改造方法:


    if
    (tree[x].l==0)tree[x].l=y; else { int k=tree[x].l; while(tree[k].r)k=tree[k].r; tree[k].r=y; }

    tree[y].r = tree[x].l; tree[x].l = y;

    之后再考虑转移,对于这个题来说,我们想要得到关于父节点的信息,就必须先处理完它的左右子树。

    注意对于每个节点,这个节点可以不取而直接去取它的兄弟。

    先处理每个节点的兄弟,在每个节点枚举向左可以放多少人,向右可以放多少人,更新过程递归实现。

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    int n,m;
    int a[1006],dp[1006][1006];
    struct ahah{
        int l,r;
    }tree[1006<<2];
    int dfs(int k,int sum)
    {
        if(!sum||!k)return 0;
        if(dp[k][sum]!=-1)return dp[k][sum];
        int ans=dfs(tree[k].r,sum);
        for(int i=0;i<sum;i++)
        {
            ans=max(ans,dfs(tree[k].l,i)+dfs(tree[k].r,sum-i-1)+a[k]);
        }
        dp[k][sum]=ans;
        return ans;
    }
    int main()
    {
        memset(dp,-1,sizeof(dp));
        int x,y;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&x,&y);
            if(tree[x].l==0)tree[x].l=y;
            else
            {
                int k=tree[x].l;
                while(tree[k].r)k=tree[k].r;
                tree[k].r=y;
            }
        }
        printf("%d",dfs(tree[0].l,m));
    }
  • 相关阅读:
    C++ Primer 随笔 Chapter 2 变量和基本类型
    比较全面的gdb调试命令 (转载)
    open和fopen的区别(转)
    来了
    Function语义学之member function
    TCP/IP学习(四)TCP缓冲区大小及限制(转)
    TCP连接的建立和终止
    Data 语义学(2)
    Data 语义学(1)
    一个类到底有多大?
  • 原文地址:https://www.cnblogs.com/rmy020718/p/9592484.html
Copyright © 2011-2022 走看看