zoukankan      html  css  js  c++  java
  • 没有上司的舞会(选择类树形DP)

    传送门

    题意:学校内有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个舞会,舞会每邀请来一个职员都会增加一定的快乐指数Ri,但是,如果某个职员的上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了.求最大的快乐指数。

    分析:一道经典的选择类树形DP问题.既然题目都直白地告诉了说具有树形关系,所以dfs从根节点层层递归下去把树构建出来.根节点当然就是校长了,即没有直接上司的人.设pd[i]表示i有无上司,则有pd[root]=0;

    设f[x][0/1]分别表示x不参加/参加舞会的最大快乐指数.既然有两种状态,就有两种转移.

    第一种情况:x不参加舞会,则x的下属y可能参加,也可能不参加.

    f[x][0]=max(f[x][0],max(f[x][0]+f[y][1],f[x][0]+f[y][0]))

    第二种情况:x参加舞会,则x的下属y不可能参加

    f[x][1]=max(f[x][1],f[x][1]+f[y][0])

    P.S.应该是数据太水,这样讨论就直接一遍过了,看了一下题解,每个人的转移都有一点差别...

    int n,root;
    int pd[6005],f[6005][2];
    vector<int>q[6005];
    //q[x]记录q的下属有哪些,相当于直接用vector存图了
    void dfs(int x){
        for(int i=0;i<q[x].size();i++){
    		int y=q[x][i];
    		dfs(y);
    		f[x][0]=max(f[x][0],max(f[x][0]+f[y][1],f[x][0]+f[y][0]));
    		f[x][1]=max(f[x][1],f[x][1]+f[y][0]);
        }
        return;
    }
    int main(){
        n=read();
        for(int i=1;i<=n;i++)f[i][1]=read();
        for(int i=1;i<=n-1;i++){
    		int a=read(),b=read();
    		q[b].push_back(a);//a是b的下属之一
    		pd[a]=1;
        }
        int a=read(),b=read();
    //根据题意最后还会输出两个0,吞掉.
        for(int i=1;i<=n;i++){
    		if(pd[i]==0){
    	    	root=i;
    	    	break;
    		}
        }//找到根节点
        dfs(root);//从根节点开始dfs
        printf("%d
    ",max(f[root][0],f[root][1]));
        return 0;
    }
    
    
  • 相关阅读:
    Docker 私有仓库搭建
    事务提交与不同数据库的自增方式
    多环境切换&&注解方式&&增删改返回值问题
    查询缓存&&逆向工程
    Mybatis整合Log4j、延迟加载
    关联查询
    MyBatis实现动态SQL
    输出参数resultType
    MyBatis调用存储过程执行CRUD
    两种取值符号的异同
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10370277.html
Copyright © 2011-2022 走看看