【樹狀DP】沒有上司的晚會
阿新 • • 發佈:2018-12-09
心累.jpg
新知識掌握的過程不會總是順利的。
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
輸出最大的快樂指數。
思路
這****的儲存結構,令人抓狂
DP,用類似連結串列的東東存下職員們之間的關係,用了一大堆陣列。。。
。
。
。
已知,如果i職員被選去了晚會,那麼他的下屬一定不會去。
(但下屬的下屬是可以去的)
So,
我們就用f[i][1]表示他會去的最大快樂值,
f[i][0]表示他不會去的。
(此快樂值是隻考慮他和他的下屬的最優情況)
那麼f[i][1]=他的快樂指數+他的下屬不會去的快樂值。
f[i][0]=他所有屬下去或不去的快樂值(大的那個)
因為,i不去,他屬下也不一定會去,要是他屬下不去所能獲得的快樂值大於他屬下去的快樂值,那麼f[i][0]就加上他屬下不去的快樂值。
每個屬下都這樣判斷一遍。
超級亂的程式碼
待加註釋。。。
#include<cstdio>
#define ST 6001
using namespace std;
int max(int a,int b){ //求最大值
if(a>b) return a;
return b;
}
struct N{
int n,to,next;
} k[ST];
int head[ST],n,tot=0,a[ST],f[ST][ST]={0};
bool kkk[ST];
void add(int i,int j){
k[++tot].n=i;
k[tot].to=j;
k[ tot].next=head[i];
head[i]=tot;
kkk[j]=true;
}
void init(){
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=1;i<n;++i){
int j,l;
scanf("%d%d",&j,&l);
add(l,j);
}
}
void cc(int now){
f[now][1]=a[now];
for(int i=head[now];i;i=k[i].next)
{
cc(k[i].to);
f[now][1]=f[now][1]+f[k[i].to][0];
f[now][0]=max(f[k[i].to][1],f[k[i].to][0])+f[now][0];
}
}
int main(){
init();
int l;
for(int i=1;i<=n;++i)
if(kkk[i]==false) {
l=i;
break;
}
cc(l);
if(f[l][1]>f[l][0]) printf("%d",f[l][1]);
else printf("%d",f[l][0]);
}