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 ;
}

最新文章

  1. input文本框设置和移除默认值
  2. iOS,视图相关
  3. iOS 开发之使用safari对webview进行调试
  4. 通过颜色代码初始化UIColor
  5. 【java基础】重载与重写
  6. JAVA设计模式之桥梁模式
  7. mysql概要(十五)存储过程
  8. MVC如何配置才能访问静态页面
  9. MySQL密码忘记之解决方法
  10. js简繁转换,两种实现方式,妥妥的~
  11. sgu 194 被动散热器具有最大流量的上限和下限(最大流量模板dinic加上优化)
  12. Android Toolbar 标题居中及字体样式自定义
  13. 03 SeekBar 音频播放拖拽进度条
  14. Thread和Runnable的区别和联系、多次start一个线程会怎么样
  15. 用KendoGrid控件 快速做CRUD
  16. Machine Learning--week3 逻辑回归函数(分类)、决策边界、逻辑回归代价函数、多分类与(逻辑回归和线性回归的)正则化
  17. 第5天(半天)【shell编程初步、grep及正则表达式】
  18. Flask学习-前言
  19. Spark RDD深度解析-RDD计算流程
  20. 利用Jquery和fullCalendar制作日程表

热门文章

  1. Ganglia3.1.7安装与配置(收录)
  2. Android stadio bug
  3. Notepad++删除空行的多种实现办法
  4. Linux(centos)搭建SVN服务器完美方案及遇到的问题--费元星站长
  5. ActiveMQ测试实例
  6. 【目录】Spring 源码学习
  7. nodejs的交叉(跨平台)编译(to android)
  8. Qt Qwdget 汽车仪表知识点拆解4 另类进度条实现
  9. [OpenCV]DMatch类和KeyPoints类:特征点匹配
  10. 5.爬虫 requests库讲解 高级用法