http://acm.hust.edu.cn/vjudge/problem/14338

题意:给定一棵树,每个点有一个值,让你选择k个点,并且这k个点是连在一起的(从任意一个点出发,可以遍历完所有选择的点 并且 不经过没有被选择的点),让这k个点的价值总和最大,纹方案数(Mod1000000007)。

题解:设d[x][k]为必须选择x,以x为根的子树中共选择了k个节点,价值总和最大是多少。

f[x][k]为d[x][k]对应的方案数是多少。

对于x,我们把x的孩子son不断地并到f[x]中。

对于每一个son:d[x][j]=maxx(d[x][j-k],d[son][k]);

需要注意的就是上式中d[x][j]不断地变化,对于当前的son,j变大的时候可能用到的d[x][j-k]是用当前的son更新的。所以要开一个p[x][j]等于当前的son没更新x的时候d[x][j]的值,同理q[x][j]=f[x][j]。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; typedef long long LL;
const int N=;
const LL Inf=(LL)1e9,Mod=;
struct node{
int x,y,next;
}a[*N];
int len,n,m,r;
int first[N],son[N],w[N];
LL a1,a2,d[N][N],f[N][N],p[N][N],q[N][N]; void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=first[x];first[x]=len;
} void dfs(int x,int fa)
{
son[x]=;
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(y==fa) continue;
dfs(y,x);
son[x]+=son[y];
}
} void copy(int x)
{
for(int i=;i<=n;i++) p[x][i]=d[x][i],q[x][i]=f[x][i];
} void dp(int x,int fa)
{
for(int i=;i<=n;i++) d[x][i]=-Inf;
memset(f[x],,sizeof(f[x]));
d[x][]=;f[x][]=;d[x][]=w[x];f[x][]=; copy(x); for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(y==fa) continue;
dp(y,x);
for(int j=;j<=son[x];j++)
{
for(int k=;k<=son[y] && (j-k)>=;k++)
{
LL dd=p[x][j-k]+d[y][k];
LL ff=(q[x][j-k]*f[y][k])%Mod;
if(dd > p[x][j])
{
if(dd>d[x][j]) d[x][j]=dd,f[x][j]=ff;
else if(dd==d[x][j]) f[x][j]=(f[x][j]+ff)%Mod;
}
else if(dd == p[x][j])
{
if(dd==d[x][j]) f[x][j]=(f[x][j]+ff)%Mod;
}
}
}
copy(x);
} if(d[x][m]>a1) a1=d[x][m],a2=f[x][m];
else if(d[x][m]==a1) a2=(a2+f[x][m])%Mod;
} int main()
{
freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
len=;
memset(first,,sizeof(first));
scanf("%d%d%d",&n,&m,&r);
for(int i=;i<=n;i++) scanf("%d",&w[i]);
for(int i=;i<=r;i++)
{
int x,y;
scanf("%d%d",&x,&y);
x++;y++;
ins(x,y);ins(y,x);
}
dfs(,);
a1=-Inf;
dp(,);
printf("%I64d %I64d\n",a1,a2);
}
return ;
}

【UVALive4685-Succession】树形DP的更多相关文章

  1. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  2. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  3. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  4. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  5. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

  6. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  7. POJ2342 树形dp

    原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...

  8. hdu1561 The more, The Better (树形dp+背包)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...

  9. bzoj2500: 幸福的道路(树形dp+单调队列)

    好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...

  10. BZOJ 1040 树形DP+环套树

    就是有n个点n条边,那么有且只有一个环那么用Dfs把在环上的两个点找到.然后拆开,从这条个点分别作树形Dp即可. #include <cstdio> #include <cstrin ...

随机推荐

  1. webapi到处excel

    最近项目用的webapi前几天做了个导出excel功能,给大家分享下,自己也记录下... 在用的过程中,可以直接请求就可以得到下载的excel文件,在实际的项目中可以通过js打开新页面,encodeU ...

  2. ORB-SLAM 代码笔记(二)

    ORB-SLAM中除了第三方库,基本没有看到使用c++11的新特性(例如别的SLAM框架中常用的智能指针,拷贝控制,泛型算法等,基本没有使用动态内存,栈内存读取速度较快),因此非常适合初学,代码很清晰 ...

  3. 高德API+.NET解决租房问题(JS相关)

    在线地址:58同城品牌公寓高德搜房 Github地址:https://github.com/liguobao/58HouseSearch 知乎专栏(点赞用的):高德API+Python解决租房问题(. ...

  4. Flask 中文手册 0.10 文档

    Flask 中文手册 0.10 文档 欢迎使用 Flask 欢迎阅读 Flask 文档. 本文档分为几个部分.我推荐您先从 安装 开始,之后再浏览 快速入门 章节. 教程 比快速入门更详细地介绍了如何 ...

  5. 我的阿里之路+Java面经考点

    我的阿里之路+Java面经考点 时间:2018-03-19 23:03  来源:未知   作者:admin   点击:87次 我的2017是忙碌的一年,从年初备战实习春招,年三十都在死磕JDK源码,三 ...

  6. JVM运行内存分配和回收

    本文来自网易云社区 作者:吕宗胜 Java语言与C语言相比,最大的特点是编程人员无需过多的关心Java的内存分配和回收,因为所有这一切,Java的虚拟机都帮我们实现了.JVM的内存管理,大大降低了开发 ...

  7. 「日常训练」 Soldier and Number Game (CFR304D2D)

    题意 (Codeforces 546D) 给定一个数x=a!b!" role="presentation">x=a!b!x=a!b!的形式,问其中有几个质因数. 分 ...

  8. 「日常训练」Alena And The Heater (CFR466D2D)

    题意(Codeforces 940D) 根据给定要求构建数列,求能构建出相同数列的l和r. 分析 这题写的是真的烦.一定要想到对b串要按照5个5个的看!为什么5个5个的看?因为根据题意,是先看前4个再 ...

  9. 初探 Qt Opengl【2】

    最近在研究QOPengl QGraphicsView QGraphicsItemQGraphicsScene不过也只是皮毛,也不是做什么技术贴,就是记录一下自己在其中遇到的问题,和自己新学到的东西. ...

  10. jmeter+ant的使用

    1.安装ant 下载ant,解压到某盘 2.配置环境变量: 变量名称 变量值 备注 ANT_HOME F:\apache-ant-1.10.3 Ant的解压路径 Path %ANT_HOME%\bin ...