hdu 1520 Anniversary party(第一道樹形dp)
阿新 • • 發佈:2018-08-02
include 描述 pro ace rsa input mes red contain
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 T 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.
學校要開一個聚會。學校的教職工之間有上下級關系,為了讓所有人開心,宴會組織者決定不會同時邀請一個人和他的上級(這讓我想起我們昨天晚上聚餐李曄老師不來,她怕她來了我們放不開。。。。),對於每一個人,他能給聚會帶來的歡樂度有一個值,問組織者該邀請哪些人能夠使宴會的歡樂度達到最大值。
解題思路:
首先是DP的部分(也是很無聊的一部分):每個參與者都有兩種狀態,一種是參加,一種是不參加。這個狀態的後續影響就是如果他參加了,他的直接上司和直接下屬都不能參加。我們可以用一個二維二態的數組來描述:dp[i][1]表示第i個參與者參加了,dp[i][0]表示第i個參與者沒有參加。狀態轉移方程就是dp[i][1]=dp[i][1]+dp[i-1][0],dp[i][0]=dp[i][0]+Max(dp[i-1][0],dp[i-1][1])。 本質:將一個數字三角形的操作放在了樹上 第一道樹形dp題,紀念一下,雖然對樹的部分理解的還不是很透徹 code:
傳送門:
http://acm.hdu.edu.cn/showproblem.php?pid=1520
Anniversary party
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 16376 Accepted Submission(s): 6241
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
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
Source Ural State University Internal Contest October‘2000 Students Session
Recommend linle | We have carefully selected several similar problems for you: 1561 1011 2196 1494 2242 題目大意:
解題思路:
首先是DP的部分(也是很無聊的一部分):每個參與者都有兩種狀態,一種是參加,一種是不參加。這個狀態的後續影響就是如果他參加了,他的直接上司和直接下屬都不能參加。我們可以用一個二維二態的數組來描述:dp[i][1]表示第i個參與者參加了,dp[i][0]表示第i個參與者沒有參加。狀態轉移方程就是dp[i][1]=dp[i][1]+dp[i-1][0],dp[i][0]=dp[i][0]+Max(dp[i-1][0],dp[i-1][1])。 本質:將一個數字三角形的操作放在了樹上 第一道樹形dp題,紀念一下,雖然對樹的部分理解的還不是很透徹 code:
#include <iostream> #include <stdio.h> #include<memory> #include<stack> #include<string.h> #include<algorithm> using namespace std; #define max_v 6005 struct node { int pa,son; int next; } point[max_v]; int dp[max_v][2]; //dp[i][1]表示第i個參與者參加了,dp[i][0]表示第i個參與者沒有參加 //狀態轉移方程就: //dp[i][1]=dp[i][1]+dp[i-1][0] //dp[i][0]=dp[i][0]+Max(dp[i-1][0],dp[i-1][1]) int List[max_v]; int vis[max_v];//vis[a]=1 表示a有父節點 int value[max_v];//存值 int pos; void add(int pa,int son) { point[pos].pa=pa; point[pos].son=son; point[pos].next=List[pa]; List[pa]=pos++; } void dfs(int root) { if(List[root]==-1)//root沒有子節點了 { dp[root][1]=value[root]; dp[root][0]=0; return ; } int now=List[root]; dp[root][0]=0; dp[root][1]=value[root]; while(now!=-1) { dfs(point[now].son); dp[root][1]+=dp[point[now].son][0];//既然取了父節點的值,子節點的值就不能再取了。 //父節點的值沒有取,子節點的值分取和不取兩種情況,取其中較大的那種情況。 dp[root][0]+=max(dp[point[now].son][1],dp[point[now].son][0]); now=point[now].next;//這個子節點計算過了,就要開始計算下一個子節點了 } return ; } int main() { int n; while(cin>>n) { for(int i=1; i<=n; i++) cin>>value[i];//記錄每一個點的值 memset(List,-1,sizeof(List)); memset(vis,0,sizeof(vis)); int a,b; pos=0; while(~scanf("%d %d",&a,&b)) { if(a==0&&b==0) break; add(b,a); //將邊加入樹中 vis[a]=1; //記錄a有父節點,不可能是祖節點。 } a=1; while(vis[a]==1) a++;//找到根結點 dfs(a);//從根結點開始搜 printf("%d\n",max(dp[a][0],dp[a][1]));//取最大 } return 0; }
hdu 1520 Anniversary party(第一道樹形dp)