您的位置:首页 > 其它

hdu 5534 Partial Tree(完全背包)

2015-11-02 10:42 471 查看
题目链接: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 <cstdio>
#include <cstring>
#include <algorithm>

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
;
}

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: