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



  • 相关阅读:
    【Educational Codeforces Round 101 (Rated for Div. 2) C】Building a Fence
    【Codeforces Round #698 (Div. 2) C】Nezzar and Symmetric Array
    【Codeforces Round #696 (Div. 2) D】Cleaning
    【Codeforces Round #696 (Div. 2) C】Array Destruction
    【Educational Codeforces Round 102 D】Program
    【Educational Codeforces Round 102 C】No More Inversions
    【Good Bye 2020 G】Song of the Sirens
    【Good Bye 2020 F】Euclid's nightmare
    使用mobx入门
    requestAnimationFrame 控制速度模拟setinterval
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632285.html
Copyright © 2011-2022 走看看