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;
    }

  • 相关阅读:
    PHP中使用CURL实现GET和POST请求
    PHP 正则表达式匹配函数 preg_match 与 preg_match_all
    微信跳转黑科技:微信跳转技术让微信电商从此不缺流量
    PHP通过get方法获得form表单数据方法总结
    php获取微信基础接口凭证Access_token
    PHP命名空间与自动加载类详解
    PHP如何搭建百度Ueditor富文本编辑器
    PHP调用微博接口实现微博登录的方法示例
    PHP常用日期加减计算方法实例
    微信公众平台---带参数二维码生成和扫描事件
  • 原文地址:https://www.cnblogs.com/liulangye/p/2267646.html
Copyright © 2011-2022 走看看