您的位置:首页 > 其它

vijos 1642 班长的任务 树形dp

2016-08-10 20:14 302 查看
P1642班长的任务

背景

十八居士的毕业典礼(1)

描述

福州时代中学2009届十班同学毕业了,于是班长PRT开始筹办毕业晚会,但是由于条件有限,可能每个同学不能都去,但每个人都有一个权值,PRT希望来的同学们的权值总和最大。

十班有一个周密的电话通知网络,它其实就是一棵树,根结点为班长PRT,由她来负责通知她的下线(也就是儿子节点),下线们继续通知自己的下线(不一定每个下线都要通知),任何人都可以不去:”

为了使权值总和最大,班长想安排一下人,但是人数很多,人脑是难以应付的,所以她找到十八居士,让他编程用电脑解决。

格式

输入格式

输入第一行两个整数n,m表示有n位同学,至多只能去m位同学。(1<=m<=n)

接下来2*n行,每两行代表一个同学的信息(如果这位同学没有子节点,就只有一行)。

每个同学的第一行两个整数p,s,表示这位同学权值为p,子节点个数s;(-100<=p<=100)

第二行s个整数,表示这位同学的子节点的编号。

班长的编号一定为1。

对于20%数据1<=n<=10

对于60%数据1<=n<=100

对于100%数据1<=n<=1000

输出格式

输出一个整数,表示权值的最大值。

样例1

样例输入1[复制]


8 5
100 2
2 3
79 2
4 5
109 3
6 7 8
100 0
100 0
100 0
101 0
108 0


样例输出1[复制]


518



提示

来源

181818181818

.何森《浅谈数据的合理组织》

#include<bits/stdc++.h>
using namespace std;
#define ll __int64
#define esp 1e-13
const int N=2e3+10,M=1e6+1000,inf=1e9+10,mod=1000000007;
int dp

;
vector<int>v
;
int w
;
int a
,hh;
int si
;
int dfs(int x)
{

a[hh++]=x;
si[x]=1;
for(int i=0;i<v[x].size();i++)
{
si[x]+=dfs(v[x][i]);
}
return si[x];
}
void init(int x,int y)
{
for(int i=0;i<=x;i++)
{
dp[i][0]=0;
for(int t=2;t<=y;t++)
dp[i][t]=-inf;
}
}
int main()
{
int x,y,z,i,t;
hh=1;
scanf("%d%d",&x,&y);
for(i=1;i<=x;i++)
{
scanf("%d%d",&w[i],&t);
while(t--){
scanf("%d",&z);
v[i].push_back(z);
}
}
dfs(1);
init(x,y);
for(i=x;i>=1;i--)
{
for(t=1;t<=y;t++)
{
dp[i][t]=max(dp[i][t],max(dp[i+1][t-1]+w[a[i]],dp[i+si[a[i]]][t]));
}
}
int ans=-inf;
for(i=0;i<=y;i++)
ans=max(ans,dp[1][i]);
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: