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;
    }
    
    
  • 相关阅读:
    软工实践寒假作业(1/2)
    javaSprintBoot技术总结
    个人作业——软件工程实践总结&个人技术博客
    个人作业软件评测
    结对第二次作业——某次疫情统计可视化的实现
    结对第一次—疫情统计可视化(原型设计)
    软工实践寒假作业(2/2)
    《软件工程》_寒假作业1_职业生涯规划
    部署前端项目和后端项目到服务器
    软件工程实践总结&个人技术博客
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10370277.html
Copyright © 2011-2022 走看看