求助!本蒟蒻花了很长时间只能得到16pts! 求巨佬!
查看原帖
求助!本蒟蒻花了很长时间只能得到16pts! 求巨佬!
84987
LJY_ljy楼主2020/7/10 22:58

RT,这是一个连一道普及难度的树形dp题都不会的小蒟蒻。

以下是本蒟蒻的16pts的代码:(只是AC了 #5 和 #13)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 120
using namespace std;

int left_son[MAXN], right_son[MAXN], value[MAXN], G[MAXN][MAXN];
int n, q, dp[MAXN][MAXN];

inline int read() {
    register int x = 0, f = 1;
    char ch = getchar();
    while (!isdigit(ch)) {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (isdigit(ch)) {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

inline void init() {
    n = read(); q = read();
    memset(G, -1, sizeof(G));
    for (register int i = 1; i < n; i++) {
        int u = read(), v = read(), w = read();
        G[u][v] = w; G[v][u] = w;
    }
}

void make_tree(int v) {
    for (register int i = 1; i <= n; i++) {
        if (G[v][i] >= 0) {
            left_son[v] = i;
            value[i] = G[v][i];
            G[v][i] = -1; G[i][v] = -1;
            make_tree(i); break;
        }
    }
    for (register int i = 1; i <= n; i++) {
        if (G[v][i] >= 0) {
            right_son[i] = G[v][i];
            G[v][i] = -1; G[i][v] = -1;
            make_tree(i); break;
        }
    }
}

int solve(int i, int j) {
    if (j == 0) return 0;
    if ((left_son[i] == 0) && (right_son[i] == 0)) return value[i];
    if (dp[i][j] > 0) return dp[i][j];
    for (register int k = 0; k < j; k++)
        dp[i][j] = max(dp[i][j], solve(left_son[i],k) + solve(right_son[i], j - k - 1) + value[i]);
    return dp[i][j];
}

int main() {
    init();
    make_tree(1);
    printf("%d\n", solve(1, q + 1));
    return 0;
}


make_tree()函数就是在建出一棵以1节点为根节点的二叉树(也就是求出每一个节点的左孩子节点和右孩子节点,然后将边权转化为点权)。

solve()函数就是在进行dp,只不过是把dp的过程从主函数中放到了一个单独的函数中(可能这样代码看起来会比较好看吧,但是在函数调用的时候可能会出现一些问题)。

巨佬求助!

@FruitCandy @暴力出奇迹 @LightningUZ @迷残云 @zhangyuhan @LLR_TEST @LHQing

2020/7/10 22:58
加载中...