zoukankan      html  css  js  c++  java
  • ural 1039. Anniversary Party 夜

    树形DP

    所有DP的思想应该都是一样的 只是换了形式而已

    用邻接表储存领导和下属的关系 表头表示领导

    从树根开始递归 以叶子节点为截止点

    joinsum[i] 表示 第 i 个人参加时最大高兴值 若i参加 他的下属则不能参加

    unjoinsum[i] 表示 第 i 个人不参加的最大高兴值 若i不参加 他的下属有参加和不参加

    两种情况 选较大的情况

    http://acm.timus.ru/problem.aspx?space=1&num=1039

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<math.h>

    using namespace std;

    long joinsum[6001];
    long unjoinsum[6001];
    int happy_value[6001];//第 n 个人的高兴值
    bool had[6001];//用来记录树根
    struct node
    {
        struct tt *next;
    }mem[6001];
    struct tt
    {
        int k;
        struct tt *next;
    };
    inline void build(int i,int j)
    {
        struct tt *t=new tt;
        t->k=j;
        t->next=mem[i].next;
        mem[i].next=t;
    }
    long dpout(int );
    long dpin(int i)//第 i 个人参加
    {
        if(joinsum[i]!=-1)
        return joinsum[i];
        if(mem[i].next==NULL)//i为 叶子
        {
            joinsum[i]=happy_value[i];
            return joinsum[i];
        }
        if(mem[i].next!=NULL)
        {
            struct tt *t=mem[i].next;
            joinsum[i]=happy_value[i];
            while(t!=NULL)
            {
                joinsum[i]+=dpout(t->k);//下属不能参加
                t=t->next;
            }
            return joinsum[i];
        }

    }
    long dpout(int i)//第 i 个人不参加
    {
        if(unjoinsum[i]!=-1)
        return unjoinsum[i];
        if(mem[i].next==NULL)//i为 叶子
        {
            unjoinsum[i]=0;
            return unjoinsum[i];
        }
        if(mem[i].next!=NULL)
        {
            unjoinsum[i]=0;
            struct tt *t=mem[i].next;
            while(t!=NULL)
            {
                unjoinsum[i]+=max(dpin(t->k),dpout(t->k));//下属可参加 可不参加
                t=t->next;
            }
            return unjoinsum[i];
        }
    }
    int main()
    {

        //freopen("D:\\6\\bin\\Debug\\hu.txt","r",stdin );
        int n,i,up,down;
        long l1,l2;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        scanf("%d",happy_value+i);
        memset(had,false,sizeof(had));//初始化全为根
        while(scanf("%d%d",&down,&up))
        {
            if(!down&&!up)
            break;
            had[down]=true;//down 不是根
            build(up,down);
        }
        for(i=1;i<=n;i++)
        {
            if(!had[i])//i 为树根
            break;
        }
        memset(joinsum,-1,sizeof(joinsum));
        memset(unjoinsum,-1,sizeof(unjoinsum));
        l1=dpin(i);//i 参加的最大高兴值
        l2=dpout(i);//i 不参加的最大高兴值
        if(l1>l2)
        printf("%ld\n",l1);
        else
        printf("%ld\n",l2);

        return 0;
    }

  • 相关阅读:
    MyBatis3-实现多表关联数据的查询
    MyBatis3-实现单表数据的增删查改
    MyBatis3-以接口方式编程
    如何识别人的技术能力和水平?
    评审的艺术——谈谈现实中的代码评审 专题
    Spring编程式和声明式事务实例讲解
    Spring Webflux: Kotlin DSL [片断]
    Spring3.1 对Bean Validation规范的新支持(方法级别验证)
    Android setImageResource与setImageBitmap的区别
    Android开发中,9-patch (九宫格)图片作为背景带来的问题
  • 原文地址:https://www.cnblogs.com/liulangye/p/2267646.html
Copyright © 2011-2022 走看看