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));
    }
  • 相关阅读:
    tornado简单的验证码
    python分页和session和计算时间差
    初始tornado框架
    Jquery小实例
    DOM+Javascript一些实例
    Javascript
    CSS拾遗+技巧集合
    css样式基础
    KVM NAT网络模式配置
    Ultimate guide to learning AngularJS in one day
  • 原文地址:https://www.cnblogs.com/rmy020718/p/9592484.html
Copyright © 2011-2022 走看看