标签:www ch 选课 int 题解 课程 2014 include
https://www.luogu.com.cn/problem/P2014
在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习。现在有 N 门功课,每门课有个学分,每门课有一门或没有直接先修课(若课程a是课程b的先修课即只有学完了课程a,才能学习课程b)。一个学生要从这些课程里选择 M 门课程学习,问他能获得的最大学分是多少?
说是题解实际是留个备份方便以后自己找。
https://www.luogu.com.cn/blog/P6174/solution-p2014
这位的题解是我见过最清新的$O(NM)$的树形背包题解了。
#include<cmath> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=305; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch=='-';ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } struct node{ int to,nxt; }e[N]; int n,m,cnt,head[N]; inline void add(int u,int v){ e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt; } int w[N],f[N][N],idx[N],sz[N],tot; void dfs(int u){ sz[u]=1; for(int i=head[u];i;i=e[i].nxt){ int v=e[i].to; dfs(v);sz[u]+=sz[v]; } idx[++tot]=u; } int main(){ int n=read(),m=read()+1; for(int i=1;i<=n;i++){ int u=read(),v=i; add(u,v);w[v]=read(); } dfs(0); for(int i=1;i<=tot;i++){ for(int j=1;j<=m;j++){ f[i][j]=max(f[i-1][j-1]+w[idx[i]],f[i-sz[idx[i]]][j]); } } printf("%d\n",f[tot][m]); return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
标签:www,ch,选课,int,题解,课程,2014,include 来源: https://www.cnblogs.com/luyouqi233/p/12403258.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。