HDU 1520 & POJ 2342 Anniversary party(樹形dp)


Anniversary party
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u



Description

There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical structure of employees. It means that the supervisor relation forms a tree rooted at the rector V. E. Tretyakov. In order to make the party funny for every one, the rector does not want both an employee and his or her immediate supervisor to be present. The personnel office has evaluated conviviality of each employee, so everyone has some number (rating) attached to him or her. Your task is to make a list of guests with the maximal possible sum of guests' conviviality ratings.

Input

Employees are numbered from 1 to N. A first line of input contains a number N. 1 <= N <= 6 000. Each of the subsequent N lines contains the conviviality rating of the corresponding employee. Conviviality rating is an integer number in a range from -128 to 127. After that go N – 1 lines that describe a supervisor relation tree. Each line of the tree specification has the form: 
L K 
It means that the K-th employee is an immediate supervisor of the L-th employee. Input is ended with the line 
0 0 

Output

Output should contain the maximal sum of guests' ratings.

Sample Input

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

Sample Output

5


題目大意:

題目大概說的是,一個公司要舉行一個party ,讓每個人參加的話就會增加一定的歡樂程度,爲了排除尷尬的場面,每個人和他的直接領導不能同時來參加,給你一個 n ,說明有 n 個人,然後 接着 n 行 表示 讓每個人去所增加的歡樂程度,接着每行輸入兩個說 l 和 k ,表示  k 是 l 的直屬上司,直到輸入爲 0 0 時該組輸入結束,輸出所能達到的最大的歡樂值。


思路分析:

每個人能不能參加與他的直屬上司參加不參加有關,如果他的上司參加了,那麼他就不能參加,如果他的上司沒參加,那麼他可以參加也可以不參加,我們現在用 dp[i][0] 表示 i 不參加的歡樂值,dp[i][1] 表示 i 參加的歡樂值,那麼我們可以推出一個狀態轉移方程

                        dp[k][1] += dp[l][0];
			dp[k][0] += max(dp[l][0],dp[l][1]);


因此,我們就可以用這個狀態轉移方程求解。


這道題出現了一個令我很無語的情況,那就是在 HDU oj 上  用 c++ 編譯器能過,而用 G++ 編譯器超時,所以大家提交的時候注意點

附上一些我找到的 c++ 與 g++ 的差別鏈接:http://blog.csdn.net/xia842655187/article/details/51329012點擊打開鏈接


附上代碼:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <string>
#define INF 0x3f3f3f3f

using namespace std;

int dp[6500][2];
int visit[6500],n,father[6500];

void dfs(int root)                           //  利用 深搜從根開始往下搜,搜到最後一層厚,慢慢的網上遞推轉移
{
	visit[root] = 1;
	for(int i = 1;i <= n;i++)
	{
		if(father[i] == root && !visit[i])        //   root 是 i 的上司,那麼就對 i 作爲一個新根進行往下搜索
		{
			dfs(i);
			dp[root][1] += dp[i][0];                 //  root 去的時候,i 肯定不能去,所以 加上 dp[i][0]
			dp[root][0] += max(dp[i][0],dp[i][1]);  //  root 不去的時候 從 i 去和不去中選一個最大值
		}
	}
}

int main()
{
	while(cin >> n)
	{
		memset(dp,0,sizeof(dp));
		for(int i = 1;i <= n;i++)
		{
			scanf("%d",&dp[i][1]);
		}
		fill(father,father + 6500,0);          //  將每個人的直屬上司初始化爲 0 
		int l ,k,root = 0;
		while(cin >> l >> k && l + k)          //  對 每個人的直屬上司進行標記
		{
			father[l] = k;
			root = k;
		}
		while(1)                               //  判斷查詢到樹的根
		{
			if(father[root] == 0)
			break;
			root = father[root];
		}
		memset(visit,0,sizeof(visit));
		dfs(root);         //  從根開始查詢
		cout << max(dp[root][0],dp[root][1]) << endl;        //  從 大 boss 去與不去中選擇一個 歡樂值最大的輸出
	}
	return 0;
}


發佈了106 篇原創文章 · 獲贊 31 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章