没有上司的舞会(洛谷p1352)
树形 DP,即在树上进行的 DP。树形DP是所有DP中较为简单的一种,因为树形DP的状态一定是每个节点的若干状态,所以很容易根据点数猜出每个点的状态个数,进一步猜出状态的表示。由于树固有的递归性质,树形 DP 一般都是递归进行的。
题目描述:
题解: 由题意描述可以知道,每个节点只有两种状态,去或者不去:我们可以定义 F(i ,0/1)代表 以 i为根的子树的最优解(第二维的值 : 0 代表不参加舞会的情况,1 代表参加舞会的情况)。 所以可以得到状态转移方程(x为 i 的儿子):
上代码:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 3e6+7;
int n;
vector<int> edge[MAX];
int dp[MAX][2];
int in[MAX];
void DFS(int x,int f)
{
//dp[x][1] = r[x]; 也可在这赋值
for(auto v: edge[x]){
if(v==f) continue;
DFS(v,x);
dp[x][0] += max(dp[v][0],dp[v][1]) ;
dp[x][1] += dp[v][0] ;
}
return ;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>dp[i][1];
int x,y;
while(cin>>x>>y&&x&&y){
edge[x].push_back(y);
edge[y].push_back(x);
in[x] ++;
}
for(int i=1;i<=n;i++)
if(in[i]==0) {
DFS(i,0);
cout<<max(dp[i][0],dp[i][1])<<endl;
return 0;
}
}