【HDOJ5534】Partial Tree(树,背包DP)
2024-10-19 16:40:15
题意:有一棵n个点的形态不定的树,每个度为i的节点会使树的权值增加f[i],求树的最大权值
n<=2015,0<=f[i]<=1e4
思路:对不起队友,我再强一点就能赛中出这题了
显然每个点的度至少为1,且度数为1的节点至少有2个(From 队友)
有一个结论:给每个点都分配1个度,剩余的度任意分配,一定能构造出对应的方案
仔细想想题面里的生成树数量不就在暗示我有类似Prufer序的性质么……序列与构造一一对应……唉太菜了
然后就是经典的完全背包问题了
每个点分配一个度之后还剩余n-2个度,每个点的分配到1之后多出来的度是[0,n-2]
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define fi first
#define se second
#define MP make_pair
#define N 2100
#define M 110000
#define eps 1e-8
#define pi acos(-1)
#define oo 1000000000
#define MOD 10007 int a[N],f[N],dp[N]; int main()
{
//freopen("hdoj5534.in","r",stdin);
//freopen("hdoj5534.out","w",stdout);
int cas;
scanf("%d",&cas);
for(int v=;v<=cas;v++)
{
int n;
scanf("%d",&n);
for(int i=;i<n;i++) scanf("%d",&a[i]);
for(int i=;i<n;i++) f[i-]=a[i]-a[];
int m=n-;
memset(dp,,sizeof(dp));
dp[]=n*a[];
for(int i=;i<=m;i++)
for(int j=;j<=i;j++) dp[i]=max(dp[i],dp[i-j]+f[j]);
printf("%d\n",dp[m]);
}
return ;
}
最新文章
- 关于Docker官方CentOS镜像无法启动mysqld的总结
- Tomcat+ssh+Mysql本地正常,远程服务器中文乱码。(转)
- JSP页面格式化货币金额,千分位
- 利用eclipse抽取 代码片段为方法
- perl常见符号
- Windows API学习---线程与内核对象的同步
- cookie记录用户名和密码
- 数学之路-分布式计算-disco(4)
- (转载)[FFmpeg]使用ffmpeg从各种视频文件中直接截取视频图片
- FreeCAD源码阅读笔记
- poj 2681 字符串
- Python时间和时间戳互相转换
- 服务端线程模型-NIO服务模型
- bootstrap-3-上传图片-列表显示
- SQL SERVER查询的临时文件路径
- RGB格式图像转化为HSV格式
- Laravel项目October安装
- MySQL 8.0有什么新功能
- Oracle 存储过程procedure之数据更新-游标
- go语言之进阶篇WriteString的使用