1. 程式人生 > >【動態規劃】沒有上司的晚會 (ssl 1607)

【動態規劃】沒有上司的晚會 (ssl 1607)

沒有上司的晚會

Description

Ural大學有N個職員,編號為1~N。他們有從屬關係,也就是說他們的關係就像一棵以校長為根的樹,父結點就是子結點的直接上司。每個職員有一個快樂指數。現在有個週年慶宴會,要求與會職員的快樂指數最大。但是,沒有職員願和直接上司一起與會。

Input

第一行一個整數N。(1<=N<=6000)

接下來N行,第i+1行表示i號職員的快樂指數Ri。(-128<=Ri<=127)

接下來N-1行,每行輸入一對整數L,K。表示K是L的直接上司。

最後一行輸入0,0。

Output

輸出最大的快樂指數。

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個人會來,每個人都有自己的happy度,部分人有自己上司(見到自己的上司就會無法發揮happy值),求最大的happy指數

解題方法:

用f[i][1](f[i][1]+=f[i的下屬][0])表示第i個人去,f[i][0](f[i][0]+=max(f[i的下屬][0],f[i的下屬][1]))表示第i個人不去,用連結串列的形式存每一條關係線的上司(x),屬下(y),頭相等的另一條線(next),再用一個head來存每個點連線下屬的線,再用遞迴來求出結果。

#include<cstdio>
#include<iostream>
using namespace std;
int n,k,l,pd[6002],a[6002],f[6002][3],head[6002];
struct abc
{
	int x,y,next;
}s[6002];
void dp(int dep)
{
	f[dep][1]=a[dep];
	for (int i=head[dep];i;i=s[i].next)
	{
		dp(s[i].y);//遞迴
		f[dep][0]+=max(f[s[i].y][1],f[s[i].y][0]);
		f[dep][1]+=f[s[i].y][0];
	}
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	  scanf("%d",&a[i]);
	for (int i=1;i<=n;i++)
	  {
	  	scanf("%d%d",&l,&k);
	  	s[i].x=k;//存上司
	  	s[i].y=l;//存下屬
	  	s[i].next=head[k];//把當前的next指向上一個head
	  	head[k]=i;//然後替代掉head
	  	pd[l]=1;//有上司
	  }
	for (int i=1;i<=n;i++)
	  if (!pd[i])//沒上司的
	    {
	    	dp(i);//遞迴
	    	printf("%d",max(f[i][1],f[i][0]));//去和不去中挑最大的
	    	break;
	    }
}