[vijos 1642]班长的任务 [树形dp]
背景
十八居士的毕业典礼(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
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
My Solution
id序列树形dp!!!
神秘!
const int maxn=1001; int d[maxn]; -------->WA!!!! int d[1001]; -------->AC!!!!
于是我改成了
const int maxn=1010; int d[maxn];
AC!!!
C++基本的东西还要多学
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<vector> 5 using namespace std; 6 #define inf 0x3f3f3f3f 7 8 inline int read(){ 9 int re=0; 10 char ch; 11 bool flag=0; 12 while((ch=getchar())!='-'&&(ch<'0'||ch>'9')); 13 ch=='-'?flag=1:re=ch-'0'; 14 while((ch=getchar())>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0'; 15 return flag?-re:re; 16 } 17 18 struct edge{ 19 int to,next; 20 edge(int to=0,int next=0): 21 to(to),next(next){} 22 }; 23 24 const int maxn=1010; 25 26 vector<edge> edges; 27 int n,m; 28 int head[maxn]; 29 int w[maxn],num[maxn]; 30 int dp[maxn][maxn]; 31 int id[maxn],count[maxn],q=0; 32 int root=1; 33 int cnt=0; 34 int ans=-inf; 35 36 inline void add_edge(int from,int to){ 37 edges.push_back(edge(to,head[from])); 38 head[from]=++cnt; 39 } 40 41 void init(){ 42 n=read(); m=read(); 43 edges.push_back(edge(0,0)); 44 for(int i=1;i<=n;i++){ 45 w[i]=read(); 46 num[i]=read(); 47 for(int j=1;j<=num[i];j++){ 48 int to=read(); 49 add_edge(i,to); 50 } 51 } 52 } 53 54 void dfs(int x){ 55 id[++q]=x; 56 count[x]=1; 57 for(int ee=head[x];ee;ee=edges[ee].next){ 58 dfs(edges[ee].to); 59 count[x]+=count[edges[ee].to]; 60 } 61 } 62 63 void solve(){ 64 memset(dp,-127,sizeof dp); 65 dfs(root); 66 for(int i=1;i<=n;i++){ 67 dp[i][0]=0; 68 dp[i][1]=w[id[i]]; 69 } 70 for(int i=n-1;i>0;i--) 71 for(int j=1;j<=m;j++) 72 dp[i][j]=max(dp[i+1][j-1]+w[id[i]],dp[i+count[id[i]]][j]); 73 for(int i=1;i<=m;i++) 74 ans=max(ans,dp[1][i]); 75 printf("%d\n",max(ans,0)); 76 } 77 78 int main(){ 79 //freopen("temp.in","r",stdin); 80 init(); 81 solve(); 82 return 0; 83 }
于是他走了 就像他没有来过一样