hdu 5534 Partial Tree(完全背包)

题目链接:hdu 5534 Partial Tree

解题思路

首先度的总和为2(n-1),并且每个节点度不为0。如果用二维dp[i][j]表示第i个节点还剩j个度的最优值,是没问题,但是复杂度为 o(n3) 。但是其实每个节点都要分配一个度,那么我们先给每个节点分配一个度,剩下n-2的度分给n个点,可以减掉一维,dp[i]表示i个度的最优值,因为度的个数是严格小于节点个数的。背包转移的权值为val[i]-val[1](可能有负数)

代码

#include 
#include 
#include 

using namespace std;
const int maxn = 3000;
const int inf = 0x3f3f3f3f;

int N, F[maxn], dp[maxn];

int solve (int n) {
    for (int i = 0; i <= n; i++) dp[i] = -inf;

    dp[0] = 0;
    for (int i = 2; i < N; i++) {
        for (int j = 0; j + i - 1 <= n; j++)
            dp[i+j-1] = max(dp[i+j-1], dp[j] + F[i]);
    }
    return dp[n];
}

int main () {
    int cas;
    scanf("%d", &cas);
    while (cas--) {
        scanf("%d", &N);
        for (int i = 1; i < N; i++) scanf("%d", &F[i]);
        int ans = F[1] * N;
        for (int i = 2; i < N; i++) F[i] -= F[1];
        printf("%d\n", ans + solve(N-2));
    }
    return 0;
}

你可能感兴趣的:(动态规划-完全背包,HDU,GRADE:B)