Luogu P2014选课

Posted labelray

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu 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: 
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选课的主要内容,如果未能解决你的问题,请参考以下文章

Luogu P2014 选课

题解Luogu P2014 选课

Luogu P2014选课

Luogu P2014 选课 (树形DP)

LuoGu P2014选课(人生第一个树上背包)

Luogu P2014 选课 题解报告