洛谷 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 }