zoukankan      html  css  js  c++  java
  • Luogu P2014 选课

    Description:

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

    Analysis:

    一棵樹:要選一門課程就必須要選它的父親,在樹上DP。
    把課程看成物品,相當於在 i 個物品裏選 j 個使得總價值最大,這就是01背包問題。
    f[i][j] := 以 i 爲根的子樹選 j 門課程的最大得分。
    最後統計時倒序循環。

    Code

    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define _rqy rqynb
    using namespace std;
    vector<int> son[333];
    int f[333][333],a[333],n,m;
    void dfs(int p)
    {
    	f[p][0] = 0;
    	for(int i = 0;i < son[p].size();++i)
    	{
    		int v = son[p][i];
    		dfs(v);
    		for(int t = m;t >= 0;--t)//now
    			for(int j = t;j >= 0;--j)//son
    			{
    				if(t - j >= 0)
    					f[p][t] = max(f[p][t],f[p][t - j] + f[v][j]);
    			}
    	}
    	if(p)
    	{
    		for(int t = m;t >= 1;--t)
    		{
    			f[p][t] = f[p][t-1] + a[p];
    		}
    	}
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i = 1;i <= n;++i)
    	{
    		int k;
    		scanf("%d%d",&k,&a[i]);
    		son[k].push_back(i);
    	}
    	memset(f,-1,sizeof(f));
    	dfs(0);
    	printf("%d
    ",f[0][m]);
    	return 0;
    }
    
    
    岂能尽如人意,但求无愧我心
  • 相关阅读:
    Java页面中文编码要转换两次encodeURI
    ajax用get刷新页面元素在IE下无效解决~~
    祝贺自己开博~~
    错误域控降级导致解析问题
    ELK 脚本自动化删除索引
    Windows针对子目录共享权限控制
    ES查询区分大小写
    Docker异常时区问题
    Docker自定义镜像无容器日志输出
    ELK时间戳
  • 原文地址:https://www.cnblogs.com/Zforw/p/11385390.html
Copyright © 2011-2022 走看看