洛谷P2014 选课(树形dp)
2017-07-17 09:26
232 查看
P2014选课
题目描述
在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习。现在有N门功课,每门课有个学分,每门课有一门或没有直接先修课(若课程a是课程b的先修课即只有学完了课程a,才能学习课程b)。一个学生要从这些课程里选择M门课程学习,问他能获得的最大学分是多少?输入输出格式
输入格式:第一行有两个整数N,M用空格隔开。(1<=N<=300,1<=M<=300)
接下来的N行,第I+1行包含两个整数ki和si,ki表示第I门课的直接先修课,si表示第I门课的学分。若ki=0表示没有直接先修课(1<=ki<=N,1<=si<=20)。
输出格式:
只有一行,选M门课程的最大得分。
输入输出样例
输入样例#1:74 22 01 04 21 71 76 22
输出样例#1:
13
/* 树形dp:f[i][j]表示以i为根节点的子树不包括i选了j门课的最大收益 转移的时候枚举i的子节点选多少门课 f[i][j]=max(f[i][j],f[i][j-k]+f[to][k]); */ #include<cstdio> #include<cstring> #include<algorithm> #defineN307 #defineM2007 usingnamespacestd; intf ,size,cnt,n,m; inthead[M]; structedge { intu,to,pre; }e[M<<1]; inlineintinit() { intx=0,f=1;charc=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} returnx*f; } inlinevoidadd(intu,intto) { e[++cnt].to=to;e[cnt].pre=head[u];head[u]=cnt; } voiddp(intx) { for(inti=head[x];i;i=e[i].pre) { inty=e[i].to;dp(y); for(inti=m+1;i>1;i--) for(intj=i-1;j>0;j--) f[x][i]=max(f[x][i],f[x][i-j]+f[y][j]); } } intmain() { intx,y; n=init();m=init(); for(inti=1;i<=n;i++) { x=init();y=init(); f[i][1]=y; add(x,i); } dp(0); printf("%d",f[0][m+1]); return0; }
相关文章推荐
- 树形DP 洛谷P2014 选课
- (洛谷P2014 选课)<树形DP>
- 树形DP 洛谷P2014 选课
- 集训-vijos选课(树形DP)
- [CODEVS1378]选课(树形dp)
- code vs 1378 选课(树形DP)
- Luogu P2014 选课___背包+树形dp
- joyOI 选课 【树形dp + 背包dp】
- codevs1378 选课 树形dp
- Vijos 1180 选课(树形DP)
- Vijos 1180 选课 [树形dp]
- 选课 树形DP 多叉树转二叉树
- codevs 1378 选课 (树形DP)
- 【codevs 1378】选课(树形dp)
- 选课 树形DP
- codevs 1378选课 树形DP
- 洛谷 2014 选课 树形DP 解题报告
- codevs 1378 选课 (树形dp)
- codevs1378 选课-树形dp
- Tyvj 1051 选课 树形dp