解题报告 『没有上司的舞会(树形动规)』

原题地址

很经典的一道树状DP题,很适合新手(比如我)用来学习或练手,首先推出状态转移方程,然后……

就没有然后了。

 

选择节点类方程:

dp[u][0] = sum(max(dp[v][1], dp[v][0]));(v是u的儿子)

你不去,那下属可以去或不去。

dp[u][1] = sum(dp[v][0]) + happy[u];(v是u的儿子)

你去了,那下属就一定不会去。

代码实现如下:

void dp(int u) {
    f[u][0] = 0;
    f[u][1] = happy[u];
    rep(i, 0, son[u].size() - 1) {
        int v = son[u][i];
        dp(v);
        f[u][0] += max(f[v][0], f[v][1]);
        f[u][1] += f[v][0];
    }
}
View Code

 

不过在这之前需要先找到根结点root,可以用一个bool数组。每读入一个结点x,如果其有上司,则bool[x]赋值为1,然后for循环,bool值为0的即为根结点root。

代码实现如下:

rep(i, 0, n - 2) {
        int u, v;
        u = read();
        v = read();
        son[v].push_back(u);
        vis[u] = 1;
    }
    rep(i, 0, n - 1)
    if (!vis[i]) {
        root = i;
        break;
    }
    dp(root);
View Code
posted @ 2019-01-19 16:56  雲裏霧裏沙  阅读(138)  评论(0编辑  收藏  举报