zoukankan      html  css  js  c++  java
  • 选课 && 有线电视网

    题目描述

    在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习。现在有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 #include<iostream>
     2 #include<cstdio>
     3 #include<vector> 
     4 #include<cstring>
     5 using namespace std;
     6 const int maxn=1007;
     7 int score[maxn],f[maxn][maxn];
     8 int n,m;
     9 vector<int>son[maxn];
    10 void search(int x){
    11     f[x][0]=0;f[x][1]=score[x];
    12     for(int i=0;i<son[x].size();i++){
    13         int y=son[x][i];
    14         search(y);
    15         for(int u=m;u>=2;u--) 
    16             for(int v=u-1;v>=0;v--)
    17                 if(u>=v) f[x][u]=max(f[x][u],f[x][u-v]+f[y][v]);
    18         if(x==0){
    19         for(int j=m;j>=0;j--)
    20             f[x][j]=max(f[x][j],f[x][0]+f[y][j]); 
    21         } 
    22     }
    23 }
    24 int main(){
    25     cin>>n>>m;
    26     for(int i=1;i<=n;i++){
    27         int fa;cin>>fa>>score[i];
    28         son[fa].push_back(i);
    29     }
    30     memset(f,-1,sizeof(f));
    31     search(0);
    32     cout<<f[0][m]<<endl; 
    33     return 0;
    34 }

     

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 #include<set>
     8 #include<map>
     9 #include<stack>
    10 #include<vector>
    11 using namespace std;
    12 const int maxn=3007;
    13 const int INF=0x7f7f7f7f;
    14 int n,m,num;
    15 int val[maxn],head[maxn],f[maxn][maxn],sz[maxn];
    16 struct Edge{
    17   int nxt,to,dis;
    18 }edge[maxn];
    19 void add(int from,int to,int dis){
    20   edge[++num].nxt=head[from];
    21   edge[num].to=to;
    22   edge[num].dis=dis;
    23   head[from]=num;
    24 }
    25 /*void dfs(int x){
    26   f[x][0]=0;
    27   if(x>n-m) {f[x][1]=val[x];return;}
    28   for(int i=head[x];i;i=edge[i].nxt){
    29     int v=edge[i].to;dfs(v);
    30     //for(int j=0;j<=sz[x];j++)
    31     //  for(int k=0;k<=sz[v];k++)
    32     //    {f[x][j]=max(f[x][j],f[v][k]+f[x][j-k]-edge[i].dis);cout<<x<<" "<<j<<" "<<f[x][j]<<endl;} 
    33     for(int j=sz[x];j>=0;j--){
    34       for(int k=0;k<=j;k++){
    35         f[x][j]=max(f[x][j],f[v][k]+f[x][j-k]-edge[i].dis);
    36         //cout<<x<<" "<<j<<" "<<f[x][j]<<endl; 
    37       }
    38     }
    39   } 
    40 } */
    41 int dfs(int x){
    42   f[x][0]=0;
    43   if(x>n-m){f[x][1]=val[x];return 1;}
    44   int tot=0;
    45   for(int i=head[x];i;i=edge[i].nxt){
    46     int v=edge[i].to;
    47     tot+=dfs(v);
    48     for(int j=tot;j>=0;j--)//防止一棵子树重复选 
    49       for(int k=0;k<=j;k++)
    50         f[x][j]=max(f[x][j],f[v][k]+f[x][j-k]-edge[i].dis);
    51   }
    52   return tot;
    53 }
    54 int main(){
    55   cin>>n>>m;memset(f,-INF,sizeof(f)); 
    56   for(int i=1;i<=n-m;i++){
    57     cin>>sz[i];
    58     for(int j=1;j<=sz[i];j++){
    59       int a,c;cin>>a>>c;
    60       add(i,a,c);
    61     }
    62   }
    63   for(int i=n-m+1;i<=n;i++) cin>>val[i];
    64   dfs(1);
    65   for(int i=m;i>=0;i--){
    66     if(f[1][i]>=0){cout<<i<<endl;return 0;}
    67   }
    68 }
  • 相关阅读:
    Java 实现 蓝桥杯 生兔子问题
    Java实现 蓝桥杯 基因牛的繁殖
    Java实现 蓝桥杯 基因牛的繁殖
    Java实现 蓝桥杯 基因牛的繁殖
    Java实现 LeetCode 33 搜索旋转排序数组
    Java实现 LeetCode 33 搜索旋转排序数组
    Java实现 LeetCode 33 搜索旋转排序数组
    深入探究VC —— 资源编译器rc.exe(3)
    深入探究VC —— 编译器cl.exe(2)
    深入探究VC —— 编译器cl.exe(1)
  • 原文地址:https://www.cnblogs.com/lcan/p/9842338.html
Copyright © 2011-2022 走看看