题目链接

CF23 E. Tree

题解

CF竟让卡常QAQ

dp+高精度

dp[x][j]表示以x为根的子树,x所属的联通块大小为j,的最大乘积(不带j这块

最后f[x]维护以x为根的子树的最大答案

有点卡内存...高精压了4位

看了题解,了解到,其实这个dp的复杂度其实是O(n^2)

每次转移是复杂度是x之前的子树的sz * 当前子树的sz

相当于之前子树所有点和当前子树的点组成的点对数

而每个点对只会在lca处被计算一次

所以复杂度O(n^2)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
inline int read() {
int x = 0,f = 1;
char c = getchar();
while(c < '0' ||c > '9')c = getchar();
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
return x * f;
} const int L = 10000;
const int maxn = 701;
const int maxlen = 61;
struct Bignum{
int num[maxlen];
int len;
Bignum () {memset(num,0,sizeof num); len = 0; }
void print() {
for(int i = len;i;-- i)
if(i != len) {
if(num[i - 1] < L / 10) {
printf("0");
if(num[i - 1] < L / 100) {
printf("0");
if(num[i - 1] < L / 1000) printf("0");
}
}
printf("%d",num[i - 1]);
} else printf("%d",num[i - 1]);
puts("");
}
} dp[maxn][maxn],Max[maxn]; Bignum operator * (Bignum a,Bignum b) {
int len = 0;
Bignum ret;
for(int i = 0;i < a.len;i ++) for(int j = 0;j < b.len;j ++) {
ret.num[i + j] += a.num[i] * b.num[j];
if(ret.num[i + j] >= L) {
ret.num[i + j + 1] += ret.num[i + j] / L;
ret.num[i + j] %= L;
}
}
len = a.len + b.len;
while(ret.num[len-1] == 0 && len > 1) len --;
ret.len = len;
return ret;
}
Bignum operator / (Bignum a,int b) {
int len = a.len;
Bignum ret;
if(!b) return ret;
for(int i = 0;i < len;i ++) {
ret.num[i] += a.num[i]* b;
if(ret.num[i] >= L) {
ret.num[i+1] += ret.num[i] / L;
ret.num[i] %= L;
}
}
while(ret.num[len] > 0) ret.num[len+1] = ret.num[len] / L, ret.num[len ++] %= L;
ret.len = len;
return ret;
}
Bignum max(Bignum a,Bignum b) {
if(a.len < b.len) return b;
if(a.len > b.len) return a;
for(int i = a.len-1;i >= 0;i --) {
if(a.num[i] < b.num[i]) return b;
if(a.num[i] > b.num[i]) return a;
}
return b;
} //-------------------------------
struct node {
int v,next;
} edge[maxn << 1];
int head[maxn],num = 0;
inline void add_edge(int u,int v) {
edge[++ num].v = v;edge[num].next = head[u];head[u] = num;
} int n;
int siz[maxn];
void dfs(int x,int fa) {
siz[x] = 1;
dp[x][1].len = 1; dp[x][1].num[0] = 1;
for(int i = head[x];i;i = edge[i].next) {
int v = edge[i].v;
if(v == fa) continue;
dfs(v,x);
siz[x] += siz[v];
}
for(int i = head[x];i;i = edge[i].next) {
int v = edge[i].v;
if(v == fa) continue;
for(int i = siz[x];i;-- i) {
if(dp[x][i].len)
for(int j = 1;j <= siz[v];++ j)
if(dp[v][j].len) dp[x][i + j] = max(dp[x][i + j],dp[x][i] * dp[v][j]);
dp[x][i] = dp[x][i] * Max[v];
}
}
for(int i = siz[x];i ;-- i) Max[x] = max(Max[x],dp[x][i] / i);
} int main() {
n = read();
for(int i = 1,u,v;i < n;++ i) {
u = read();v = read();
add_edge(u,v); add_edge(v,u);
}
dfs(1,0);
Max[1].print();

CF23 E. Tree 树形dp+高精度的更多相关文章

  1. 熟练剖分(tree) 树形DP

    熟练剖分(tree) 树形DP 题目描述 题目传送门 分析 我们设\(f[i][j]\)为以\(i\)为根节点的子树中最坏时间复杂度小于等于\(j\)的概率 设\(g[i][j]\)为当前扫到的以\( ...

  2. hdu-5834 Magic boy Bi Luo with his excited tree(树形dp)

    题目链接: Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: ...

  3. CF 461B Appleman and Tree 树形DP

    Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other ...

  4. codeforces 161D Distance in Tree 树形dp

    题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...

  5. hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。

    /** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...

  6. 5.10 省选模拟赛 tree 树形dp 逆元

    LINK:tree 整场比赛看起来最不可做 确是最简单的题目. 感觉很难写 不过单独考虑某个点 容易想到树形dp的状态. 设f[x]表示以x为根的子树内有黑边的方案数. 白边方案只有一种所以不用记录. ...

  7. Codeforces Round #263 Div.1 B Appleman and Tree --树形DP【转】

    题意:给了一棵树以及每个节点的颜色,1代表黑,0代表白,求将这棵树拆成k棵树,使得每棵树恰好有一个黑色节点的方法数 解法:树形DP问题.定义: dp[u][0]表示以u为根的子树对父亲的贡献为0 dp ...

  8. codeforces Round #263(div2) D. Appleman and Tree 树形dp

    题意: 给出一棵树,每个节点都被标记了黑或白色,要求把这棵树的其中k条变切换,划分成k+1棵子树,每颗子树必须有1个黑色节点,求有多少种划分方法. 题解: 树形dp dp[x][0]表示是以x为根的树 ...

  9. POJ 2486 Apple Tree(树形DP)

    题目链接 树形DP很弱啊,开始看题,觉得貌似挺简单的,然后发现貌似还可以往回走...然后就不知道怎么做了... 看看了题解http://www.cnblogs.com/wuyiqi/archive/2 ...

随机推荐

  1. node.js浅谈

    相信大家对node.js也很不陌生吧,现在我来总结一下常用的吧~ 我们Web全栈工程师最多的就是用Node作为后台了,Node.js虽然可以作为后台语言,但是相对于Java那些老牌后台语言真是一点优势 ...

  2. CSS变量试玩儿

    CSS很美妙,能够为您的页面穿上衣裳,各种各样五彩斑斓的衣裳,但是对于开发者来说,他又不够灵动,于是乎有了各种各样的预处理器Sass.LESS.Stylus(笔者建议Sass的SCSS语法),这些预处 ...

  3. 那些年的 网络通信之 TCP/IP 传输控制协议 ip 加 端口 ---

    /* 一个文本小写转换为大写的小程序,当客户端从键盘录入一串字符串发送到服务端服务端转换为大写返回给客户端 */ import java.io.*; import java.net.*; class ...

  4. JD m站自我解析理解

    第一步:从首页着手 文档部分:应用的是H5默认文档开头 即:<!DOCUMENT html> head部分:放了一些相关的JS,title描述,然后就是meta表述了.比较有参考的如下 & ...

  5. 用Emacs将文件加密保存

    为Emacs安装ps-ccrypt插件. 如果你在使用elpa(Emacs的一个插件管理器), 可以M-x list-packages, 从插件列表中找到 ps-ccrypt, 在该项上按i将其标记为 ...

  6. Linux - awk 文本处理工具五

    awk 线上处理常用模式 awk 处理复杂日志 6.19: DHB_014_号百总机服务业务日报:广州 到达数异常! DHB_023_号百漏话提醒日报:珠海 到达数异常! 6.20: DHB_014_ ...

  7. 银行卡号码校验算法(Luhn算法,又叫模10算法)

    有时候在网上办理一些业务时有些需要填写银行卡号码,当胡乱填写时会立即报错,但是并没有发现向后端发送请求,那么这个效果是怎么实现的呢. 对于银行卡号有一个校验算法,叫做Luhn算法. 一.银行卡号码的校 ...

  8. Javascript - Vue - vue对象

    vue提供了一整套前端解决方案,可以提升企业开发效率 vue的处理过程 app.js 项目入口,所有请求最先进入此模块进行处理 route.js 由app.js调用,处理路由的分发 controlle ...

  9. RabbitMQ消费端消息的获取方式(.Net Core)

    1[短链接]:BasicGet(String queue, Boolean autoAck) 通过request的方式独自去获取消息,断开式,一次次获取,如果返回null,则说明队列中没有消息. 隐患 ...

  10. Space Replacement

    Write a method to replace all spaces in a string with %20. The string is given in a characters array ...