题解 P1352 没有上司的舞会

题面

中考前逃来机房学树形DP和状压DP

典型的树形DP嘛。

dp数组开2维,第一维表示在第i个点,第二位表示去或不去,去为1,不去为0。

状态转移方程很简单:

当前节点不去的话,就加上儿子节点中去或不去的最大值. dp[i][0]+=max(dp[j][0],dp[j][1]);

当前节点去的话,就直接加上儿子节点不去的值和当前快乐值. dp[i][1]=dp[j][0]+happy[i];

然后找到校长的编号,往下递归就好了.

噫,代码如下:

#include<bits/stdc++.h>

using namespace std;

vector<int>fas[10010];//用vector来存树

int n,root;
int happy[10010],dp[10010][2];
bool head[10010];

void dg(int);

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",happy+i);
    }
    for(int i=1;i<=n-1;i++)
    {
        int father,son;
        scanf("%d%d",&son,&father);
        fas[father].push_back(son);//把一个节点的所有儿子存在vector里
        head[son]=true;
    }
    int a,b;
    scanf("%d%d",&a,&b);
    for(int i=1;i<=n;i++)
    {
        if(head[i]==false)//根节点没有父亲节点
        {
            root=i;
            break;
        }
    }
    dg(root);
    printf("%d",max(dp[root][1],dp[root][0]));
return 0;
}

void dg(int x)
{
    dp[x][0]=0;
    dp[x][1]=happy[x];//先赋初值,不去的话最大值为0,去的话为自己的快乐值
    for(int i=0;i<fas[x].size();i++)//遍历一个点的所有儿子
    {
        int y=fas[x][i];
        dg(y);
        dp[x][0]+=max(dp[y][0],dp[y][1]);
        dp[x][1]+=dp[y][0];
    }
}

猜你喜欢

转载自www.cnblogs.com/Hdgs3-blog/p/10877439.html
今日推荐