HDU 5534 Partial Tree [DP]

2015区域赛 长春赛区 H题
#Description
有n个点,形成生成树,每个度的权值给出
求一种生成树,使得最后总和最大
#Algorithm
完全背包问题
体积为V的背包,有N种物品,每种物品的价值是wi, 体积是vi,有无限多个,求最优放法?
关系:
总共有2(n-1)个度,有n-1种度,每种度的权值是a[i],占一个度,有无限多个,求最优?
限制:
每个点至少有1个度
改进:
不妨,先减去n个度,同时每个度的权值减去a[0]
问题变成 n-2个度中,有n-1种度,每种度的权值是a[i] - a[0]
动态规划:
dp[i]表示度数为i时的最大权值和
对于度数为i的权值a[i - 1],由于之前已经减过一次 所以度数要减1
dp[j + i] = max(dp[j + i], dp[j] + a[i])
#Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>

using namespace std;

const int maxn = 2015 + 9;
const int INF = INT_MAX;
int a[maxn];
int dp[maxn]; //度数之和为i的最大值
void solve() {
  memset(a, 0, sizeof(a));
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n - 1; ++i) {
    scanf("%d", &a[i]); // 0..n-2
  }
  int ans = a[0] * n;
  for (int i = 1; i < n - 1; ++i) {
    a[i] -= a[0];
  }
  fill(dp, dp + n, -INF);
  dp[0] = 0; //1个度数都没用 花费0
  for (int i = 1; i < n - 1; ++i) {
    for (int j = 0; i + j < n; ++j) {
      dp[j + i] = max(dp[j + i], dp[j] + a[i]);
    }
  }
  ans += dp[n - 2];
  cout << ans << endl;
}
int main() {
//  freopen("in.txt", "r", stdin);
  int t;
  scanf("%d", &t);
  for (int i = 0; i < t; ++i) {
    solve();
  }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值