选课
这道题目给出的数据是以树形结构连接的。
这题比苹果树(题目传送门)多了一个步骤就是把一棵多叉树转化为二叉树。
读入数据时把二叉树建好:把一门课的先修课作为它的父亲。一个结点的第一个孩子作为自己的左子树,其它孩子作为第一个孩子的最右树枝链,即分别做第一个孩子的右儿子、右儿子的右儿子……(左儿子右兄弟表示法)
#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]);
}

浙公网安备 33010602011771号