zoukankan      html  css  js  c++  java
  • P2014 选课(树形DP)

    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
    题解:
    这个题基本上和二叉苹果树一模一样。学到的东西:如果一个图里面有多个树,即是一个森林,我们可以将所有树的根节点连起来构成一科新树。
     1 import java.util.ArrayList;
     2 import java.util.Scanner;
     3 
     4 class node{
     5     int v;
     6     int w;
     7 }
     8 public class Main{
     9     static int n,q;
    10     static int [][] dp = new int [310][310];
    11     static int [] t = new int [310];
    12     static ArrayList<node> g[] = new ArrayList[310];
    13     static void dfs(int x,int fa){
    14         for(int i=0;i<g[x].size();i++){
    15             node now = new node();
    16             now = g[x].get(i);
    17             int to = now.v;
    18             int w = now.w;
    19             if(to==fa)
    20                 continue;
    21             dfs(to, x);
    22             for(int j=q;j>=0;j--){
    23                 for(int k=0;k<=j-1;k++){
    24                     dp[x][j] = Math.max(dp[x][j], dp[x][k]+dp[to][j-k-1]+w);
    25                 }
    26             }
    27         }
    28     }
    29     public static void main(String[] args) {
    30         Scanner cin = new Scanner(System.in);
    31         n = cin.nextInt();
    32         q = cin.nextInt();
    33         for(int i=0;i<=n;i++)
    34             g[i] = new ArrayList<node>();
    35         int a,b,c;
    36         int cnt = 0;
    37         for(int i=1;i<=n;i++){
    38             a = cin.nextInt();
    39             b = cin.nextInt();
    40             node tmp = new node();
    41             tmp.v = i;
    42             tmp.w = b;
    43             g[a].add(tmp);
    44         }
    45         dfs(0, -1);
    46         System.out.println(dp[0][q]);
    47     }
    48 }
  • 相关阅读:
    VS2008下编的程序生成的EXE 在没有安装VS2008的计算机上能运行
    GDI+使用小记
    双缓冲技术绘图
    INI文件格式及其读写
    缩放图片并保存
    按值传递&&按引用传递&&按地址传递
    傻瓜式制作的U盘winpe(支持4G以上U盘)速度超快
    vi 命令大全
    fopen和open的区别
    Linux下Socket网络编程,文件传输,数据传输的C语言例子
  • 原文地址:https://www.cnblogs.com/1013star/p/10432435.html
Copyright © 2011-2022 走看看