zoukankan      html  css  js  c++  java
  • 【u024】没有上司的舞会

    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

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


    【输入格式】

    第一行一个整数N。(1<=N<=6000) 接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127) 接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。 最后一行输入0 0

    【输出格式】

    输出最大的快乐指数。

    【数据规模】

    Sample Input1

    7
    1
    1
    1
    1
    1
    1
    1
    1 3
    2 3
    6 4
    7 4
    4 5
    3 5
    0 0
    
    

    Sample Output1

    5
    
    【题解】
    题目的意思是说某个节点如果它的"直接"上司来了,它就不能来。
    设一个数组f[i]表示i这个节点所在的人是否参加舞会所能达到的最大快乐度。其中f[i]数组有两维,f[i].fang表示i这个节点的人参加舞会,f[i].bufang表示i这个节点的人不参加舞会。
    如果i这个节点的人参加舞会。即f[i].fang,则对于i节点来说。它的儿子节点们就只能不放(不参加)。
    然后对于f[i].bufang表示i这个人不参加舞会所能达到的最大快乐度。然后对于其儿子节点们,对应的状态就可以是参加或不参加都行。
    这样进行递归。
    void dfs (int now)
    {
    for (now的所有儿子节点son)
    {
    f[son].fang = r[son];
    dfs(son);
    f[now].fang = max{f[now].fang,f[now].fang+f[son].bufang};
    f[now].bufang = max{f[now].bufang,f[now].bufang+max{f[son].bufang,f[son].fang}};
    }
    }
    从0号节点(不存在)开始。
    然后如果某个节点它没有父亲(根节点),那么默认就是0啦。
    即可以方便找到根节点,不用特判。
    最后输出f[0].bufang.(肯定不放是最优的。如果放了的话根节点咋办????)
    【代码】
    #include <cstdio>
    
    struct data2 //存放的状态
    {
    	int fang, bufang;
    };
    
    int n, r[6001], fa[6001] = { 0 };
    data2 f[6001] = { 0 };
    
    int max(int a, int b)//返回a和b中的较大值。
    {
    	return a>b ? a : b;
    }
    
    void dfs(int now)//当前到了now这个节点。接下来要寻找到它的儿子们。
    {
    	for (int son = 1; son <= n; son++)
    		if (fa[son] == now)//如果它的爸爸是now。
    		{
    			f[son].fang = r[son];//表示其先等于快乐值(放)
    			//你完全可以再写上一句f[son].bufang= 0
    			dfs(son);//递归儿子
    			f[now].bufang = max(f[now].bufang, max(f[now].bufang + f[son].fang, f[now].bufang + f[son].bufang));//如果不放,
    			//则儿子有什么状态都能递增上去,取最优值即可
    			f[now].fang = max(f[now].fang, f[now].fang + f[son].bufang);
    			//如果放了的话,儿子当中就只能取不放的状态了。同样取最优值。
    		}
    }
    
    int main()
    {
    	//	freopen("E:\rush.txt","r",stdin);
    	scanf("%d", &n);
    	for (int i = 1; i <= n; i++)
    		scanf("%d", &r[i]);
    	int x0, y0;
    	scanf("%d%d", &x0, &y0);//输入数据
    	while (x0 != 0)
    	{
    		fa[x0] = y0;//记录谁的爸爸是谁。。。
    		scanf("%d%d", &x0, &y0);
    	}
    	dfs(0);//从0开始递归
    	printf("%d
    ", f[0].bufang);//最后输出0不放的结果.(最优值)
    	return 0;
    }



  • 相关阅读:
    iOS开发UI篇—Quartz2D使用(绘图路径)
    iOS开发UI篇—Quartz2D简单使用(三)
    iOS开发UI篇—Quartz2D使用(图片剪切)
    WordPress主题开发: 制作文章页面single.php
    Wordpress页面判断
    为WordPress某个文章添加额外的样式
    Wordpress本地伪静态设置
    Wordpress添加关键词和描述
    Wordpress制作sidebar.php
    Wordpress固定链接设置
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632285.html
Copyright © 2011-2022 走看看