zoukankan      html  css  js  c++  java
  • 洛谷P2014 选课

    题目描述

    在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习。现在有(N)门功课,每门课有个学分,每门课有一门或没有直接先修课(若课程(a)是课程(b)的先修课即只有学完了课程(a),才能学习课程(b))。一个学生要从这些课程里选择(M)门课程学习,问他能获得的最大学分是多少?

    输入输出格式

    输入格式:

    第一行有两个整数N,M用空格隔开。
    ((1 leq N leq 300,1 leq M leq 300))

    接下来的(N)行,第(I+1)行包含两个整数(k_i)(s_i, k_i)表示第I门课的直接先修课,(s_i)表示第(I)门课的学分。若(k_i=0)表示没有直接先修课((1<=k_i<=N, 1<=s_i<=20))。

    输出格式:

    只有一行,选(M)门课程的最大得分。

    输入输出样例

    输入样例#1:

    7  4
    2  2
    0  1
    0  4
    2  1
    7  1
    7  6
    2  2
    

    输出样例#1:

    13
    

    思路:数据范围也不是特别大,可以考虑树型(dp),首先,建图就是按照题目所给的信息建有向边,之后我们用(f[i][j])表示以(i)为顶点,选了(j)门课程的最大得分,然后(dfs)时枚举每条与一个点相连的边,用这个结点去更新它的子节点为顶点时的初始值,然后遍历完它所有的子节点之后,再回过头来更新这个结点为顶点时的最大值。

    代码:

    #include<cstdio>
    #include<algorithm>
    #define maxn 307
    using namespace std;
    int n,m,head[maxn],f[maxn][maxn],w[maxn],num;
    struct node {
      int v,nxt;
    }e[maxn];
    inline void ct(int u, int v) {
      e[++num].v=v;
      e[num].nxt=head[u];
      head[u]=num;
    } 
    void dfs(int u, int k) {
      for(int i=head[u];i;i=e[i].nxt) {
      	int v=e[i].v;
      	for(int j=k+1;j<=m+1;++j) f[v][j]=f[u][j-1]+w[v];
      	dfs(v,k+1);
      	for(int j=k+1;j<=m+1;++j) f[u][j]=max(f[u][j],f[v][j]);
      }
    }
    int main() {
      scanf("%d%d",&n,&m);
      for(int i=1,u;i<=n;++i) {
      	scanf("%d%d",&u,&w[i]);
      	ct(u,i);
      }
      dfs(0,1);
      printf("%d
    ",f[0][m+1]);
      return 0;
    }
    
  • 相关阅读:
    JavaScript之事件冒泡和事件捕获详细介绍
    jQuer配合CSS3实现背景图片动画
    jQuery中animate()的方法以及$("body").animate({"scrollTop":top})不被Firefox支持问题的解决
    JavaScript 运用之表单验证(正则)和控制输入长度。
    input[type=submit]以及数字日期在苹果手机上显示异常的处理
    webstorm 快捷键
    Bootstrap 折叠(Collapse)插件
    input输入内容时放大问题及处理
    省市二级联动(原生JS)
    Spring4.X——搭建
  • 原文地址:https://www.cnblogs.com/grcyh/p/10201366.html
Copyright © 2011-2022 走看看