洛谷 P2014 选课

P2014 选课

先将这棵树转化成二叉树

dp[i][j]表示以第i门科目为根节点的子树选j门科目最大的学分

记忆化搜索

k是枚举左儿子选的科目数

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 1999
 4 int n,m,fa[maxn],ls[maxn],rs[maxn],w[maxn],dp[maxn][maxn];
 5 
 6 int dfs(int i,int j)
 7 {
 8     if(i>n||j>m||i<1||j<1) return 0;
 9     if(dp[i][j]) return dp[i][j];
10     for(int k=0;k<j;k++)
11         dp[i][j]=max(dp[i][j],dfs(ls[i],k)+dfs(rs[i],j-k-1)+w[i]);
12     dp[i][j]=max(dp[i][j],dfs(rs[i],j));
13     return dp[i][j];
14 }
15 
16 int main()
17 {
18     scanf("%d%d",&n,&m);
19     for(int i=1;i<=n;i++) scanf("%d%d",&fa[i],&w[i]);
20     for(int i=1;i<=n;i++)
21     {
22         if(!ls[fa[i]]) ls[fa[i]]=i;
23         else{
24             int dad=ls[fa[i]];
25             while(rs[dad]) dad=rs[dad];
26             rs[dad]=i;
27         }
28     }
29     printf("%d\n",dfs(ls[0],m));
30     return 0;
31 }
View Code

 

posted @ 2017-09-12 20:21  Alex丶Baker  阅读(165)  评论(0编辑  收藏  举报