题意:有一棵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 ;
}

最新文章

  1. 关于Docker官方CentOS镜像无法启动mysqld的总结
  2. Tomcat+ssh+Mysql本地正常,远程服务器中文乱码。(转)
  3. JSP页面格式化货币金额,千分位
  4. 利用eclipse抽取 代码片段为方法
  5. perl常见符号
  6. Windows API学习---线程与内核对象的同步
  7. cookie记录用户名和密码
  8. 数学之路-分布式计算-disco(4)
  9. (转载)[FFmpeg]使用ffmpeg从各种视频文件中直接截取视频图片
  10. FreeCAD源码阅读笔记
  11. poj 2681 字符串
  12. Python时间和时间戳互相转换
  13. 服务端线程模型-NIO服务模型
  14. bootstrap-3-上传图片-列表显示
  15. SQL SERVER查询的临时文件路径
  16. RGB格式图像转化为HSV格式
  17. Laravel项目October安装
  18. MySQL 8.0有什么新功能
  19. Oracle 存储过程procedure之数据更新-游标
  20. go语言之进阶篇WriteString的使用

热门文章

  1. 更改 Linux 语言为中文
  2. ATM-db-dnhandler
  3. C语言的位运算的优势 !
  4. MongDB之各种新增操作
  5. MTCNN学习资源
  6. 【Gas Station】cpp
  7. PHP 命名空间和自动加载
  8. Linux下librtmp使用及编程实战
  9. c++中读取文件最快的方法
  10. 兼容浏览器 回车键 keydown事件