题目描述

在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习。现在有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:

7  4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
输出样例#1:

13
 

Solution

这个题算是树上背包入门题了.

很简单的DP思路.

状态定义:

f[ i ] [ j ] 表示当前 i 这个节点,已经选了 j 个的最大价值

状态转移:

for ( j=m ; j--> 1;j-- )

for ( k=1 ; k<=m; k++ )

f [ now ] [ j ] = max ( f[ now ][ j ], f[ now ][ j-k ]+f[ to ][ k ]);

类似于01背包的转移方程,只是把它放到了树上而已.

然后我进行了一个预处理,预先将每个节点的子树节点个数记录起来,然后在转移的时候就只要转移 min (num[now],m );

优化到了 0ms.

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=; struct sj{
int to;
int next;
}a[maxn];
int c[maxn],v[maxn],ans;
int size,head[maxn],n,m;
int f[maxn][maxn],num[maxn]; void add(int x,int y)
{
a[++size].to=y;
a[size].next=head[x];
head[x]=size;
} void pre(int x)
{
num[x]=;
for(int i=head[x];i;i=a[i].next)
{
int tt=a[i].to;
if(!num[tt])
{
pre(tt);
num[x]+=num[tt];
}
}
f[x][]=c[x];
return;
} void dfs(int x)
{
for(int i=head[x];i;i=a[i].next)
{
int tt=a[i].to;
dfs(tt);
int jj=min(m,num[x]);
for(int j=jj;j>=;j--)
for(int k=;k<j;k++)
f[x][j]=max(f[x][j],f[tt][k]+f[x][j-k]);
}
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
c[i]=y; add(x,i);
}
m++;
//此处因为 0 对于答案不算体积.
pre();
dfs();
cout<<f[][m]<<endl;
return ;
}

最新文章

  1. 安卓真机调试 出现Installation error: INSTALL_FAILED_UPDATE_INCOMPATIBLE....
  2. Android课程---视图组件总结(2)
  3. JAVA 1.1
  4. OpenGL ES 中的模板测试
  5. [Java面试三]JavaWeb基础知识总结.
  6. javaweb回顾第十篇JSTL
  7. spring项目中使用weblogic的连接池
  8. Android——ProgressDialog 进度条对话框
  9. 【转】armeabi和armeabi-v7a
  10. Django数据库操作(增删改查)
  11. php 运行的四种模式
  12. 操作系统--进程管理(Processing management)
  13. (线性dp 最大子段和 最大子矩阵和)POJ1050 To the Max
  14. 通过flask实现web页面简单的增删改查bootstrap美化版
  15. 组合数的求法 (n&lt;=1e8 可以过来看)
  16. css文件放在根目录之后不起作用原因
  17. Android.mk高级写法
  18. js 控制输入文字个数(换行不算)
  19. Windows下Python IDLE设置
  20. linux_添加定时任务,每5min清理下某个文件夹下的文件

热门文章

  1. CodeForces 219D Choosing Capital for Treeland (树形DP)
  2. Objective-C中关于NSArray, NSDictionary, NSNumber等写法的进化
  3. 多源最短路径 – Floyd-Warshall Algorithm
  4. URL URI URN的区别
  5. 一、numpy入门
  6. CPP-网络/通信:COM
  7. HTML5拖放(drag和drog)作品
  8. ios copy assign retain
  9. javascript(九)事件冒泡 onmouseenter onmouseenter 默认事件 和 键盘事件
  10. 永久激活IDEA的方法