选课

题面

这道题目给出的数据是以树形结构连接的。

这题比苹果树(题目传送门)多了一个步骤就是把一棵多叉树转化为二叉树。

读入数据时把二叉树建好:把一门课的先修课作为它的父亲。一个结点的第一个孩子作为自己的左子树,其它孩子作为第一个孩子的最右树枝链,即分别做第一个孩子的右儿子、右儿子的右儿子……(左儿子右兄弟表示法)

#include<iostream>
#include<cstdio>
using namespace std;
int n,m;
struct node{
    int lson,rson;
}a[305];
bool gotson[305];
int dp[305][305],s[305];
void DP(int rc,int rm)
{//if一定要打,要不然会回到虚根导致dp错误
    if(dp[rc][rm]) return;
    if(a[rc].rson)
    DP(a[rc].rson,rm);
    dp[rc][rm]=dp[a[rc].rson][rm];
    for(int k=1;k<=rm;k++){
        if(a[rc].lson)
        DP(a[rc].lson,k-1);
        if(a[rc].rson)
        DP(a[rc].rson,rm-k);
        dp[rc][rm]=max(dp[rc][rm],dp[a[rc].lson][k-1]+dp[a[rc].rson][rm-k]+s[rc]);
    }

}
int main(void)
{
    scanf("%d%d",&n,&m);
    for(int i=1,k;i<=n;++i)
    {
        scanf("%d%d",&k,s+i);
        if(gotson[k])
        {
            k=a[k].lson;
            while(a[k].rson) k=a[k].rson;//找最深的右儿子
            a[k].rson=i;
        }
        else {
            gotson[k]=1;a[k].lson=i;
        }//多叉转二叉树
    }
    DP(0,m+1);
    printf("%d",dp[0][m+1]);
}

  

posted @ 2019-07-25 14:03  [jackeylove]  阅读(99)  评论(0编辑  收藏  举报