码迷,mamicode.com
首页 > 其他好文 > 详细

【Luogu P2014】选课

时间:2018-04-09 00:18:15      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:高等数学   学生   return   数学   很多   cin   sam   i++   课程   

题目描述

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

int m,n,F,s[310],son[310][310],f[310][310],ans;

void dfs(int fa){
    for(int i=1;i<=son[fa][0];i++){
        int y=son[fa][i];
        dfs(y);
        for(int j=m;j>=0;j--)
            for(int k=j;k>=0;k--)
                if(j>=k)
                    f[fa][j]=max(f[fa][j],f[fa][j-k]+f[y][k]);
        
    }
    if(fa!=0)
        for(int j=m;j>0;j--)
            f[fa][j]=f[fa][j-1]+s[fa];
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>F>>s[i];
        son[F][++son[F][0]]=i;
    }
    dfs(0);
    for(int i=m;i>=0;i--)
        ans=max(ans,f[0][i]);
    cout<<ans<<endl;
    return 0;
}

 

【Luogu P2014】选课

标签:高等数学   学生   return   数学   很多   cin   sam   i++   课程   

原文地址:https://www.cnblogs.com/labelray/p/8747870.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!